设计模式15 命令模式

命令模式与策略模式的UML类图比较接近,先直观的对比一下。左图:命令模式,右图:策略模式。

可以看出,命令模式的“上部分”就是策略模式,是在策略模式的基础上,增加了receiver类型。

命令模式(Command)定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

命令模式的优点有:

1、降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。

2、增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。

3、可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。

4、方便实现 Undo 和 Redo 操作。命令模式可以与备忘录模式结合,实现命令的撤销与恢复。

命令类:

 1 public interface Command {
 2     public void execute();
 3 }
 4 
 5 public class ConcreteCommandA implements Command {
 6     private ReceiverA receiver;
 7 
 8     public ConcreteCommandA() {
 9         receiver = new ReceiverA();
10     }
11 
12     @Override
13     public void execute() {
14         // TODO Auto-generated method stub
15         receiver.action();
16     }
17 }
18 
19 public class ConcreteCommandB implements Command {
20     private ReceiverB receiver;
21 
22     public ConcreteCommandB() {
23         receiver = new ReceiverB();
24     }
25 
26     @Override
27     public void execute() {
28         // TODO Auto-generated method stub
29         receiver.action();
30     }
31 }

接收者类:

public class ReceiverA {
    public void action() {
        System.out.println("A接收命令");
    }
}

public class ReceiverB {
    public void action() {
        System.out.println("B接收命令");
    }
}

命令触发类:

 1 public class Invoker {
 2     private Command command;
 3 
 4     public void setCommand(Command command) {
 5         this.command = command;
 6     }
 7 
 8     public Invoker(Command command) {
 9         this.command = command;
10     }
11 
12     public void call() {
13         command.execute();
14     }
15 }

调用方式:

 1 public class Client {
 2     /*
 3      * 命令对象command中包含了具体的操作,
 4      * 客户端只需要调用命令,无需关心具体的操作。
 5      */
 6     public static void main(String[] args) {
 7         //扩展点
 8         Command command;
 9 
10         //使用命令A
11         command = new ConcreteCommandA();
12 
13         //稳定代码
14         Invoker invoker = new Invoker(command);
15         invoker.call();
16         
17         //切换命令B
18         command = new ConcreteCommandB();
19         invoker.setCommand(command);
20         invoker.call();
21     }
22 }

执行结果:

原文地址:https://www.cnblogs.com/asenyang/p/12111067.html