命令模式

……

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

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

/**
*
* 命令模式
*
* 命令模式使用对象封装一系列操作(命令),使得操作可以重复使用,也易于在对象间传递。首先来一个传统Java方式实现的命令模式代码。
*/
class Light {
public void on() {
System.out.println("light turn on");
}
public void off() {
System.out.println("light turn off");
}
}

interface Command {
void execute();
}

class FilpUpCommand implements Command {
private Light light;
public FilpUpCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}

class FilpDownCommand implements Command {
private Light light;

public FilpDownCommand(Light light) {
this.light = light;
}

@Override
public void execute() {
light.off();
}
}

/**
* 以上代码中,灯(Light)是命令(Command)的操作对象(Receiver)。
* 我们定义了命令的协议,同时我们实现两个具体的命令操作:FlipUpCommand和FlipDownCommand。它们分别使灯亮,和使灯灭。
*/
class LightSwitch{
private List<Command> queue=new ArrayList<>();

public void addCommand(Command cmd){
queue.add(cmd);
}

public void execute(){
for(Command cmd:queue){
cmd.execute();
}
}
}

/**
* 上面的代码首先创建了一个命令执行者LightSwitch,并创建一个客户对象来使用命令;
* 在函数式编程中,由于存在高阶函数。我们可以直接将一个函数作为参数传给另外一个函数。
* 所以,使用类包裹函数在对象间传递这件事情就显得多余了。以下代码显示如何使用高阶函数达到命令模式相同的效果:
*/
class Client{

public static void pressSwitch(){
Light lamp=new Light();
Command flipUpCommand=new FilpUpCommand(lamp);
Command flipDowomnCmand=new FilpDownCommand(lamp);

LightSwitch lightSwitch = new LightSwitch();
lightSwitch.addCommand(flipUpCommand);
lightSwitch.addCommand(flipDowomnCmand);
lightSwitch.addCommand(flipUpCommand);
lightSwitch.addCommand(flipDowomnCmand);

lightSwitch.execute();
}
}




class LightSwitchFP {
private List<Consumer<Light>> queue = new ArrayList<>();
public void addCommand(Consumer<Light> cmd) {
queue.add(cmd);
}
public void execute(Light light) {
for (Consumer<Light> cunsumer : queue) {
cunsumer.accept(light);
}
}
}

class Client1 {
public static void pressSwitch() {
Light lamp = new Light();
Consumer<Light> flipUp = light -> {light.on();};
Consumer<Light> flipDown = light -> {light.off();};
Consumer<Light> flipUp1 = Light::on;
Consumer<Light> flipDown1 = Light::off;
LightSwitchFP lightSwitch = new LightSwitchFP();
lightSwitch.addCommand(flipUp);
lightSwitch.addCommand(flipDown);
lightSwitch.addCommand(flipUp);
lightSwitch.addCommand(flipDown);

lightSwitch.execute(lamp);
}
}