设计模式-命令模式

在软件开发过程中,经常需要在一个对象中调用另外一个对象的方法去执行某种操作,但是调用方可能需要执行不同对象的方法;这时候可以考虑使用命令模式,来减少调用方和执行方的耦合,让调用方不用关注具体的执行方是谁,也不需要关注具体的实现;命令模式的主要特点就是通过引入command对象,使得命令的调用方和具体执行方解耦;

1.组成结构

设计模式-命令模式

1>Invoker

命令的调用方,就是谁要来执行操作的,它通过command对象来执行命令,会持有一个command的引用,如果是批量处理命令的话,会有一个command 队列的引用;

2>Command

抽象命令类,包含一个execute方法用来执行命令;在Invoker中会进行调用execute方法;

3>ConcreteCommand

具体的命令类,实现了Command抽象类的execute方法,会调用receiver.action方法来完成命令的执行;

4>Receiver

命令的执行者,来执行命令的具体的操作的;会有一个action方法,被ConcreteCommand来调用;

具体的代码

1.Invoker

public class Invoker {

    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }

    public void doSomething() {
        this.command.execute();
    }
}

2.抽象Command

public abstract class Command {

    public abstract void execute();

}

3.ConcreteCommand

public class ConcreteCommandA extends Command {

    public Receiver receiver;

    public ConcreteCommandA(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        this.receiver.action();
    }
}

4.Receiver

public class Receiver {

    public void action(){
        System.out.println("具体执行命令!!");
    }
}

2. 理解

为什么要通过command来做一个中间类,而不是直接在invoker类中调用receiver的action方法执行对应的操作哪?主要是为了解耦;如果直接调用就耦合了

Invoker invoker = new Invoker(receiver)
invoker.doSomeThing()

这样的话,如果说invoker要调用其他的操作就不行了;通过引入Command,可以注入不同的具体的command来执行操作,系统的灵活性大大提升;举个例子比如有个设置快捷键的功能,针对某一个快捷键A,可以设置为打印,也可以设置为删除,复制等操作;我们就可以把这些操作抽象成命令,这样的话,可以随便设置,而不固定于某一种操作;这就是命令模式的优点所在;另外命令模式也可以实现批处理的命令执行,这时候需要把调用方Invoker中添加一个Command队列的引用;

class CommandQueue {  
    //定义一个ArrayList来存储命令队列  
    private ArrayList<Command> commands = new ArrayList<Command>();  
      
    public void addCommand(Command command) {  
        commands.add(command);  
    }  
      
    public void removeCommand(Command command) {  
        commands.remove(command);  
    }  
      
    //循环调用每一个命令对象的execute()方法  
    public void execute() {  
        for (Object command : commands) {  
            ((Command)command).execute();  
        }  
    }  
}  
class Invoker {  
    private CommandQueue commandQueue; //维持一个CommandQueue对象的引用  
      
    //构造注入  
    public Invoker(CommandQueue commandQueue) {  
        this. commandQueue = commandQueue;  
    }  
      
    //设值注入  
    public void setCommandQueue(CommandQueue commandQueue) {  
        this.commandQueue = commandQueue;  
    }  
      
    //调用CommandQueue类的execute()方法  
    public void call() {  
        commandQueue.execute();  
    }  
}  

总结:命令模式的优点有

1>降低系统的耦合性,通过引入了一个command,解耦了命令的调用方和执行方;

2>新的命令可以很方便的加入到系统中,扩展性很好,直接添加command的具体实现即可;

3>可以很容易的实现队列,请求的撤销和恢复;

当然缺点就是引入了大量的类,每增加一种命令的操作就引入了一个新的类去处理