2

目录

  1. 命令模式

  2. 为什么使用命令模式

  3. 命令模式应用实例

命令模式

命令模式:在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合,比如要对行为进行“记录、撤销/重做、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)

从上面对于命令模式的定义也反映出了为什么要使用命令模式,通过将一系列的操作封装成一个命令对象,方便执行,同时也能够很好的让我们进行一些操作回滚,用来记录是否执行过该操作等问题。

为什么使用命令模式

当我们有一系列任务要进行处理,也就是很多方法,而且这些任务之间没有明显的先后顺序,而我们只有一个线程用来执行任务,比如某个物品的装配任务,不同的人采用了不同的装配顺序,假设不同装配顺序都可产生该产品,但是只有一个装配机器进行装配任务,因此我们不可能将每个装配步骤写在装配机器程序中,因为每个人的装配步骤是不同的,所以每个用来执行装配任务的机器必须能够进行动态的调整,所以这个时候命令模式的作用发挥出来了,我们可以这样架构该系统。代码如下:

/定义一个命令接口
public interface Command{
    public void execute();
    public void undo();
}

//其中的一个命令继承自这个接口
public class addPatCommand implements Command{
    public void execute(){
        doSomething...
    }
    public void undo(){
        undo...
    }
}

//执行者,用来执行命令
public class Executer{
    //命令队列
    ArrayList<Command>commandList = new ArrayList<Command>();
    //记录当前已经执行的命令
    int executed = 0;
    //执行命令
    public void execute(){
        if(commandList.size()==0)
            System.out.println("Please add a command");
        else{
            for(int i=executed; i<commandList.size(); i++){
                commandList.get(i).execute();
            }
            executed = commandList.size();
        }
    }
    //添加命令
    public void addCommand(Command mCommand){
        commandList.add(mCommand);
    }
    //执行撤销命令,回滚到执行前
    public void undo(){
        if(executed==0)
            System.out.println("Do Nothing");
        else{
            for(int i=executed; i>=0; i--){
                commandList.get(i).undo();
            }
        }
    }
}

通过上面的代码,我们可能发现这有些像是之前的策略模式,对不同的行为单独进行封装,然后通过add方法将依赖实例注入,然后通过一个list持有依赖集群,然后再通过对依赖队列的遍历来执行方法,策略模式可能唯一不同的是在在内部通过委托的方式来执行方法,再就是策略模式中每个委托对象所要被调用的方法不同,而且每个注入的实例也将会被用到不同的方法之中,而命令模式则是将其置于一个方法之中。

命令模式应用实例

数据库中的事务,可以通过这种方式来实现回滚,日常安排,线程池,工作队列等,通过着我们可以很好的实现被操作对象和操作者之间的解耦,同时还可以实现撤销操作。
Android中的Thread通过构造函数接纳实现了Runnable接口的类,这个运用的就是命令模式,当然我们平常更多会是通过匿名内部类的形式来将依赖实例注入。

下篇更代理模式,侧重下其和委托形式的区别和实际应用。


Jensen95
2.9k 声望534 粉丝

连续创业者。