设计模式之命令模式

       操做数据库时有各类操做,即有插入,删除,又有更新。各类操做间,其实能够当作咱们给数据库发送命令,让它根据咱们的命令执行相应的操做。操做模式中的命令模式刚好能够很好的封装命令。咱们并不须要数据库作了什么具体的操做,咱们须要的就是发出一个命令,以后数据库按照咱们的命令作相应的操做。java

1、定义

定义(来源:维基百科)Command pattern)是一种设计模式,它尝试以命令來表明实际操做。命令类能够把行动(action) 及其参数封装起來,因而這些行动能够被:重复屡次、取消后又重作数据库

看了百度百科的定义,感受不是太好理解,因而我把维基百科的定义从新修饰了一下。设计模式

要点解析:bash

一、经过命令来表示实际的操做。咱们平时写代码基本就是须要什么功能,则直接调用某方法,而命令模式是经过发送一个命令的方式。markdown

二、命令在执行前是能够被取消、或者重复执行同一个命令的。ide

看了定义可能你还云里雾里的,不是特别清楚命令模式是怎么回事?别急,你如今只要清楚:1客户端经过发送命令来作具体的操做。二、操做执行前是能够取消掉的。this

2、UML

先来看看命令模式下,都涉及到哪些角色:spa

一、首先必须有命令类,因而咱们须要一个命令的抽象类、以下图中的Command类。设计

二、其次,须要有具体的命令类,你究竟是请求删数据呢,仍是新增数据呢?你得定义删除,新增的命令,以下图中的InsertCommand、DeleteCommand、UpdateCommand。code

三、须要有个类来接收客户端发送过来的命令,管理这些命令,由于这些命令还须要能够撤销。下图中的Invoke。

四、发送命令过来的本质仍是执行命令表明的具体逻辑,因此还须要有个地方实现这些逻辑,这个角色以下图的Receiver类,实现具体逻辑



3、代码实现

接下来看看数据库操做场景下,命令模式的实现例子

(一)、定义命令的抽象类

package com.design.command;

public abstract class Command {
    //持有具体逻辑操做的引用
    protected Receiver receiver;

    public Command(Receiver receiver) {
        this.receiver = receiver;
    }
    //执行命令的具体逻辑
    public abstract void execute();
}复制代码

(二)、具体的命令

package com.design.command;

/**
 * 插入命令
 */
public class InsertCommand extends Command {
    //要插入到数据库的数据
    private String dat;
    public InsertCommand(Receiver receiver) {
        super(receiver);
    }
    //执行插入操做
    @Override
    public void execute() {
        receiver.insertData(dat);
    }

    public String getDat() {
        return dat;
    }

    public void setDat(String dat) {
        this.dat = dat;
    }
}复制代码

package com.design.command;

/**
 * 删除命令
 */
public class DeleteCommand extends Command {
    //要删除数据库的数据
    private String dat;

    public DeleteCommand(Receiver receiver) {
        super(receiver);
    }

    @Override
    public void execute() {
        super.receiver.deleteData(dat);
    }

    public String getDat() {
        return dat;
    }

    public void setDat(String dat) {
        this.dat = dat;
    }
}复制代码

package com.design.command;

/**
 * 更新命令
 */
public class UpdateCommand extends Command {

    private String dat;

    public UpdateCommand(Receiver receiver) {
        super(receiver);
    }

    @Override
    public void execute() {
        receiver.updateData(dat);
    }

    public String getDat() {
        return dat;
    }

    public void setDat(String dat) {
        this.dat = dat;
    }
}
复制代码

(三)、具体实现功能的类

package com.design.command;

public class Receiver {

    /**
     *实现插入指令的功能
     * @param data
     */
    public void insertData(String data){
        System.out.println("插入数据库数据:"+data);
    };

    /**
     *实现删除指令的功能
     * @param data
     */
    public void deleteData(String data){
        System.out.println("删除数据库数据:"+data);
    };

    /**
     *实现更新指令的功能
     * @param data
     */
    public void updateData(String data){
        System.out.println("更新数据库数据:"+data);
    };
}复制代码

(四)、Invoke类,对接客户端,接收客户端发来的命令

package com.design.command;

import java.util.ArrayList;
import java.util.List;

public class Invoker {
    //经过一个ArrayList来存储客户端发送过来的命令
    private List<Command> commandList = new ArrayList<>();
    //增长命令
    public void addCommand(Command command){
        this.commandList.add(command);
    }
    //取消命令
    public void cancelCommand(Command command){
        this.commandList.remove(command);
    }
   //通知所有命令
    public void executeAllCommand(){
        for (Command command : commandList){
            command.execute();
        }
        commandList.clear();
    }

}复制代码

(五)、看看怎么来调用

package com.design.command;

public class TestMain {

    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        //建立插入指令
        InsertCommand insertCmand = new InsertCommand(receiver);
        insertCmand.setDat("用户名为:zhangsan");
        //建立删除指令
        DeleteCommand delCmand = new DeleteCommand(receiver);
        delCmand.setDat("用户名为:lisi");
        //建立更新指令
        UpdateCommand updateCamd = new UpdateCommand(receiver);
        updateCamd.setDat("更新zhangsan用户名为王五");

        Invoker invoker = new Invoker();
        //发送插入指令
        invoker.addCommand(insertCmand);
        //发送删除指令
        invoker.addCommand(delCmand);
        //取消删除指令
        invoker.cancelCommand(delCmand);
        //发送更新指令
        invoker.addCommand(updateCamd);
        //执行全部指令
        invoker.executeAllCommand();
    }
}
复制代码

(六)、执行结果


能够看到,咱们发送了删除命令,以后咱们作了取消命令的操做,因此最后并无执行取消操做,只执行了插入和更新操做。

4、结论

到此,命令模式的说明还有例子都已经呈现。作个总结:命令模式的做用其实就是将之前直接调用逻辑换成经过发送命令的方法,这个可让咱们客户端根具体的逻辑之间进行解耦。其次可轻松实现命令的记录,还有命令的取消、命令的重复等操做。

(一)、优势

一、如上表述、可解耦客户端与具体逻辑。

二、可方便对执行的操做进行记录,如咱们能够在Invoke类中对执行的命令进行记录。

三、扩展性好,新增命令简单,只需新增长具体命令类。

四、可进行命令撤销,重复执行命令等。

(二)、缺点

一、可能会形成具体的命令类过多。

相关文章
相关标签/搜索