设计模式之禅——命令模式

引:作为领导人只要发布命令即可,而不用在发布命令的时候还要去找到实施的人,我相信领导人一定超级高兴,因为实施的人已经包含在命令里了。这就是命令模式

定义

将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。——行为类

命令模式是一个高内聚模式。它的封装性非常好,把请求方(Invoker)和执行方(Receiver)封开了。

它的通用类图如下:

image

通用代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// 通用Receiver类
public abstract class Receiver {
// 抽象接收者,定义每个接收者都必须完成的业务
public abstract void doSomething();
}

// 具体的Receiver类,可以是N个,和业务有关
public class ConcereteReceiver1 extends Receiver {
// 每个接收者都必须处理一定的业务逻辑
public void doSomething(){}
}
public class ConcereteReceiver2 extends Receiver {
// 每个接收者都必须处理一定的业务逻辑
public void doSomething(){}
}

// 抽象的Command类
public abstract class Command {
// 每个命令类都必须有一个执行命令的方法
public abstract void execute();
}

// 具体的Command类
public class ConcreteCommand1 extends Command {
//关联,对哪个Receiver类进行命令处理
private Receiver receiver;
// 构造函数传递接收者
public ConcreteCommand1(Receiver _receiver) {
this.receiver = _receiver;
};
// 必须实现一个命令
public void execute() {
// 业务处理
this.receiver.doSomething();
}
}
public class ConcreteCommand2 extends Command {
//关联,对哪个Receiver类进行命令处理
private Receiver receiver;
// 构造函数传递接收者
public ConcreteCommand2(Receiver _receiver) {
this.receiver = _receiver;
};
// 必须实现一个命令
public void execute() {
// 业务处理
this.receiver.doSomething();
}
}

// 调用者Invoker类
public class Invoker {
private Command command;
// 接受命令
public void setCommand(Command _command) {
this.command = _command;
}
// 执行命令
public void action(){
this.command.execute();
}
}

// 场景类
public class Client {
public static void main(String[] args) {
// 首先声明调用者Invoker
Invoker invoker = new Invoker();
// 定义接收者
Receiver receiver = new ConcreteReceiver1();
// 定义一个发送给接受者的命令
Command command = new ConcreteCommand1(receiver);
// 把命令交给调用者去执行
invoker.setCommand(command);
invoker.action();
}
}

应用

优点

  1. 类间解耦:调用者与接收者之间没有任何依赖关系,调用者实现功能时只需要调用Command抽象类的execute方法即可,不需要了解是哪个接收者执行。
  2. 可扩展性:Command的子类非常容易扩展。
  3. 命令模式结合其他模式会更优秀,例如责任链模式,模板方法模式。

缺点

有N个命令就会有N个Command的子类,这样这个类就会膨胀了。

使用场景

只要是你认为是命令的地方就可以采用命令模式。

最佳实践

根据开发场景要求可以有多个接收者,那就需要用集合类型来封装Command类了。该设计模式最大的优点就是高层模式不需要知道接收者,Perfect!

参考

  1. 《设计模式之禅》