Earth Guardian

You are not LATE!You are not EARLY!

0%

设计模式--行为型:命令模式

命令模式:将请求封装为一个对象,从而可以将不同的请求作为参数来传递。对请求排队或记录日志,以及支持可撤销的操作

命令模式

命令模式 Command Pattern:类似系统菜单,比如开机、关机、重启、注销等等,这些动作都封装成命令对象,作为参数记录并执行。
命令模式可以对发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求,这就是命令模式的模式动机。

类图结构

0063-Command-uml-classdiag.png

结构解析

  • Command
    接口,定义所有的命令。
  • ConcreteCommand
    实现类,具体不同的命令。
  • Invoker
    请求者,也是命令发送者,记录命令并做出具体的命令请求。
  • Receiver
    接收者,接收命令并执行具体的命令。
  • Client
    客户端。

示例

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
78
79
80
81
82
83
84
// 1. Command
public interface Command {
void execute();
}

// 2. ConcreteCommand
public class FlipUpCommand implements Command {
private Receiver receiver;

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

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

public class FlipDownCommand implements Command {
private Receiver receiver;

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

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

// 3. Invoker
public class Invoker {
private List<Command> commands = new ArrayList<>();

public void add(Command command){
commands.add(command);
}

public void execute(Command command){
if (!commands.contains(command)){
add(command);
}else {
command.execute();
}
}

public void remove(Command command){
commands.remove(command);
}
}

// 4. Receiver
public class Receiver {

public void turnOn(){
System.out.println("Receiver, Light: turn On.");
}

public void turnOff(){
System.out.println("Receiver, Light: turn Off.");
}
}

// 5. Client
public class TestCommand {
public static void main(String[] args) {
Receiver light = new Receiver();

FlipUpCommand upCommand = new FlipUpCommand(light);
FlipDownCommand downCommand = new FlipDownCommand(light);

Invoker invoker = new Invoker();
invoker.add(upCommand);
invoker.add(downCommand);

invoker.execute(upCommand);
invoker.remove(downCommand);
}
}

// 6. Result
Receiver, Light: turn On.

总结

命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开,降低了系统耦合度,同时很容易增加新命令,但是会导致过多的具体命令类。

参考文档

  • 大话设计模式
  • Android 源码设计模式解析与实战
  • 命令模式