设计模式——Command模式

什么是Command模式

所谓命令模式,必然存在三个角色——命令发起者、命令、命令接收者。即命令这个角色使发起者和接收者实现了解耦。试想一下,如果没有中间层命令,那么命令发起者必须聚合接收者,如果有了命令,那么发起者和接受者则通过命令来实现联系。

Command的UML图

UML

Command是一个接口,其中定义了执行和撤销的方法,而ConcreteCommand是实现了Command的具体命令,这个具体命令是Invoker(发起者)和Receiver(接收者)的“桥梁”。

代码实现

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
public interface Command {

void execute();

void undo();

}

// 执行命令的接收者
public class CommandReceiver {

public void on() {
System.out.println("on");
}

public void off() {
System.out.println("off");
}

}

// 具体的命令角色 拥有命令接受者 并调用接收者的action
public class LightOnCommand implements Command {

private CommandReceiver commandReceiver;

public LightOnCommand(CommandReceiver commandReceiver) {
this.commandReceiver = commandReceiver;
}

@Override
public void execute() {
commandReceiver.on();
System.out.println("light on");
}

@Override
public void undo() {
commandReceiver.off();
System.out.println("light off");
}

}

public class LightOffCommand implements Command{

private CommandReceiver commandReceiver;

public LightOffCommand(CommandReceiver commandReceiver) {
this.commandReceiver = commandReceiver;
}

@Override
public void execute() {
commandReceiver.off();
System.out.println("light off");
}

@Override
public void undo() {
commandReceiver.on();
System.out.println("light on");
}

}

// 空命令 也是一种设计模式 是我们少做空判断 加强逻辑
public class NoCommand implements Command {

@Override
public void execute() {

}

@Override
public void undo() {

}
}

// 命令发起者 聚合的是命令的集合或者单个命令
public class RemoteControl {

private Command[] onCommands = new Command[5];

private Command[] offCommands = new Command[5];

private Command undoCommand = new NoCommand();


public Command[] getOnCommands() {
return onCommands;
}

public void setOnCommands() {
onCommands[0] = new LightOnCommand(new CommandReceiver());
}

public Command[] getOffCommands() {
return offCommands;
}

public void setOffCommands() {
offCommands[0] = new LightOffCommand(new CommandReceiver());
}

public void onButton(int n) {
undoCommand = this.onCommands[n];
this.onCommands[n].execute();
}

public void offButton(int n) {
undoCommand = this.offCommands[n];
this.offCommands[n].execute();
}

public void undo() {
undoCommand.undo();
}

}

// 客户端调用

public class Client {

public static void main(String[] args) {

RemoteControl remoteControl = new RemoteControl();
remoteControl.setOnCommands();
remoteControl.setOffCommands();

remoteControl.onButton(0);
remoteControl.offButton(0);
remoteControl.undo();

}

}

Command模式的优点和不足

实现命令发起者和接受者之间的解耦,命令发起者不需要知道接受者是谁。

容易设计一个命令队列,并使用多线程去操作。

但是提高了系统的复杂度,可能会导致命令的具体类过多。

-------------本文结束感谢阅读-------------