文章

23种设计模式----命令模式----行为型模式

命令模式1.什么是命令模式2.命令模式的角色3.模式图4.例子4.1例子背景4.2 结构图4.3 命令接口4.4 命令抽象方法4.5 实现的命令4.6 命令的集合4.7 抽象的持有者4.8 实现的持有者4.9 命令的发动者4.10 命令的请求者4.11 结果5.总结5.1 命令的享元工厂5.2 执行者的享元工厂5.2.1抽象的命令的集合:5.2.2具体的命令的集合5.2.3 抽象的命令的发动者5...._设计模式23模式介绍知乎

23种设计模式----命令模式----行为型模式

文章信息

  • 原文链接:https://jiayq.blog.csdn.net/article/details/85170621
  • 发布时间:2018-12-21 19:43:41
  • 阅读量:486
  • 分类:java同时被 2 个专栏收录, 订阅专栏, 设计模式
  • 标签:#命令模式, #23种设计模式, #行为型模式, #重构, #享元模式

摘要

文章浏览阅读486次。命令模式1.什么是命令模式2.命令模式的角色3.模式图4.例子4.1例子背景4.2 结构图4.3 命令接口4.4 命令抽象方法4.5 实现的命令4.6 命令的集合4.7 抽象的持有者4.8 实现的持有者4.9 命令的发动者4.10 命令的请求者4.11 结果5.总结5.1 命令的享元工厂5.2 执行者的享元工厂5.2.1抽象的命令的集合:5.2.2具体的命令的集合5.2.3 抽象的命令的发动者5…._设计模式23模式介绍知乎


命令模式

  • 1.什么是命令模式
  • 2.命令模式的角色
  • 3.模式图
  • 4.例子
    • 4.1例子背景
      • 4.2 结构图
      • 4.3 命令接口
      • 4.4 命令抽象方法
      • 4.5 实现的命令
      • 4.6 命令的集合
      • 4.7 抽象的持有者
      • 4.8 实现的持有者
      • 4.9 命令的发动者
      • 4.10 命令的请求者
      • 4.11 结果
  • 5.总结
    • 5.1 命令的享元工厂
      • 5.2 执行者的享元工厂
        • 5.2.1抽象的命令的集合:
          • 5.2.2具体的命令的集合
          • 5.2.3 抽象的命令的发动者
          • 5.2.4 具体的命令的发动者
      • 5.2.5 调用者
        • 5.2.6 结果
          • 5.2.7 说明

23种设计模式

1.什么是命令模式

命令就是需要自己命令的对象进行的操作。

首先,分为两个方面:
对于命令方,命令是最小单位。
对于被命令方,命令是最大单位。

其次:
命令有发出角色,有执行角色。
同时:
命令有发出时间,有执行时间。

等等。

所以,命令模式主要解决就是把一系列复杂的操作,(相对不变)封装起来,等到需要再次调用时,不需要创建,只需要调用即可。
命令模式大大的降低了使用者的条件,但是却可能变相的增加提供者的条件。

举个例子:使用接口封装的服务,可能对于提供者来说比较容易实现,但是对于调用者来说,调用可能比较困难。
而使用命令模式,可以大大的较低调用者的使用难度,相应的,提供者的提供难度将会增加。

2.命令模式的角色

抽象的命令:定义命令需要实现什么操作
实现的命令 :抽象的命令进行实现
命令的执行者:命令将由这个角色进行执行
命令的请求者:发起命令的角色
命令的发动者:决定何时执行命令

一般来说:命令的请求者持有命令,实现的命令持有命令的执行者,命令的执行者决定时间。

3.模式图

实现

持有

持有

决定

实现的命令

抽象的命令

命令的执行者

命令的请求者

命令的发动者

从上图可以看出,命令模式几乎完全解耦了调用者和提供者的关系。
调用者几乎不需要了解操作是如何实现的。
调用者只需要发起命令的请求。

4.例子

实例源码下载传送门(资源暂未审核,通过后及时增加)

4.1例子背景

现在生活条件上升,很多人都有了自己的小汽车,所以,很多人都会开车。
下面的例子就是关于如何开车。
首先,开车的步骤大家都知道。
举一个例子:起步:
起步需要:

  • 系安全带
  • 左转向灯
  • 左转向
  • 刹车
  • 点火
  • 离合
  • 挂挡
  • 给油
    为了简单,在本次例子中,离合就认为是踩下离合并且在合适的时间释放离合,刹车也是,给油认为是根据需要踩给油踏板。

4.2 结构图

在这里插入图片描述
在这里插入图片描述

4.3 命令接口

1
2
3
4
5
6
7
package order.intf;

public interface IntfCommand {

	void execute();
	
}

4.4 命令抽象方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package order.abs;

import order.intf.IntfCommand;
import receive.abs.AbsCar;

public abstract class AbsCommand implements IntfCommand{

	protected AbsCar absCar;
	
	public AbsCommand(){
		init();
	}
	
	protected abstract void init();

	@Override
	public void execute() {
		System.out.println(this.getClass() + "\texecute\t"
				+ this);
		absCar.receive();
	}
	
}

4.5 实现的命令

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
package order.command;

import order.abs.AbsCommand;
import receive.component.BrakeRec;

/**
 * 
 * 刹车
 */
public class BrakeComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new BrakeRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.ClutchRec;

/**
 * 
 * 离合
 */
public class ClutchComm extends AbsCommand {

	@Override
	protected void init() {

		absCar = new ClutchRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);

	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.HangOutRec;

/**
 * 
 * 挂挡
 */
public class HangOutComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new HangOutRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.IgnitionRec;

/**
 * 点火
 *
 */
public class IgnitionComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new IgnitionRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.OilRec;

/**
 * 给油
 *
 */
public class OilComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new OilRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.PutOutRec;

/**
 * 
 * 熄火
 */
public class PutOutComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new PutOutRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.SteeringWheelLeftRec;

/**
 * 
 * 左打方向盘
 */
public class SteeringWheelLeftComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new SteeringWheelLeftRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}





package order.command;

import order.abs.AbsCommand;
import receive.component.SteeringWheelRightRec;

/**
 * 
 * 右打方向盘
 */
public class SteeringWheelRightComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new SteeringWheelRightRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}





package order.command;

import order.abs.AbsCommand;
import receive.component.TurnSignalLeftRec;

/**
 * 
 * 左转向灯
 */
public class TurnSignalLeftComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new TurnSignalLeftRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}





package order.command;

import order.abs.AbsCommand;
import receive.component.TurnSignalRightRec;

/**
 * 
 * 右转向灯
 */
public class TurnSignalRightComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new TurnSignalRightRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}




package order.command;

import order.abs.AbsCommand;
import receive.component.WearingSeatbeltRec;

/**
 * 
 * 系安全带
 */
public class WearingSeatbeltComm extends AbsCommand {

	@Override
	protected void init() {
		absCar = new WearingSeatbeltRec();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + absCar.getClass() + ":"
				+ absCar);
	}

}

4.6 命令的集合

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
package order.step;

import java.util.LinkedList;
import java.util.Queue;

import order.command.BrakeComm;
import order.command.ClutchComm;
import order.command.HangOutComm;
import order.command.IgnitionComm;
import order.command.OilComm;
import order.command.SteeringWheelLeftComm;
import order.command.TurnSignalLeftComm;
import order.command.WearingSeatbeltComm;
import order.intf.IntfCommand;

/**
 * 车起步:
 * 
 * 系安全带
 * 左转向灯
 * 左转向
 * 刹车
 * 点火 
 * 离合
 * 挂挡
 * 给油
 *
 */
public class CarStart implements IntfCommand{

	private Queue<IntfCommand> step = new LinkedList<IntfCommand>();
	
	public CarStart() {
		
		init();
		
	}
	
	private void init(){
		
		step.add(new WearingSeatbeltComm());
		step.add(new TurnSignalLeftComm());
		step.add(new SteeringWheelLeftComm());
		step.add(new BrakeComm());
		step.add(new IgnitionComm());
		step.add(new ClutchComm());
		step.add(new HangOutComm());
		step.add(new OilComm());
		
		System.out.println(this.getClass().getName() + "\tinit\t"
				+ step.getClass().getName());
	}
	
	@Override
	public void execute() {
		System.out.println(this.getClass() + "\texecute\t"
				+ this);
		IntfCommand command = step.poll();
		while(command != null){
			command.execute();
			command = step.poll();
		}
		
	}


}

4.7 抽象的持有者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package receive.abs;



public abstract class AbsCar {

	
	public void receive(){
		System.out.println(this.getClass() + "\treceive\t"
				+ this);
		doReceive();
	}
	
	protected abstract void doReceive();
	
}

4.8 实现的持有者

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 刹车
 */
public class BrakeRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("刹车");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 离合
 */
public class ClutchRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("离合");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 挂挡
 */
public class HangOutRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("挂挡");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 点火
 *
 */
public class IgnitionRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("点火");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 给油
 *
 */
public class OilRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("给油");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 熄火
 */
public class PutOutRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("熄火");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 左打方向盘
 */
public class SteeringWheelLeftRec extends AbsCar {

	@Override
	protected void doReceive() {

		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("左打方向盘");

	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 右打方向盘
 */
public class SteeringWheelRightRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("右打方向盘");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 左转向灯
 */
public class TurnSignalLeftRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("左转向灯");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 右转向灯
 */
public class TurnSignalRightRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("右转向灯");
		
	}

}





package receive.component;

import receive.abs.AbsCar;

/**
 * 
 * 系安全带
 */
public class WearingSeatbeltRec extends AbsCar{

	@Override
	protected void doReceive() {
		
		System.out.println(this.getClass() + "\tdoReceive\t"
				+ this);
		System.out.println("系安全带");
		
	}

}

4.9 命令的发动者

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
package receive.car;

import receive.abs.AbsCar;

/**
 * 车起步:
 * 
 * 系安全带 左转向灯 左转向 刹车 点火 离合 挂挡 给油
 *
 */
public class CarStart extends AbsCar {

	private order.step.CarStart carStart;

	public CarStart() {

		init();
	}

	private void init() {
		carStart = new order.step.CarStart();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + carStart.getClass() + ":"
				+ carStart);
	}

	@Override
	protected void doReceive() {
		System.out.println(this.getClass().getName() + "\tdoReceive\t"
				+ this.getClass());
		carStart.execute();
	}

}

4.10 命令的请求者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package client;

import receive.car.CarStart;

public class Main {

	public static void main(String[] args) {

		System.out.println("生成命令");
		CarStart carStart = new CarStart();
		System.out.println("执行命令");
		carStart.receive();
	}

}

4.11 结果

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
生成命令
class order.command.WearingSeatbeltComm:order.command.WearingSeatbeltComm@1befab0	init	class receive.component.WearingSeatbeltRec:receive.component.WearingSeatbeltRec@13c5982
class order.command.TurnSignalLeftComm:order.command.TurnSignalLeftComm@c21495	init	class receive.component.TurnSignalLeftRec:receive.component.TurnSignalLeftRec@1d5550d
class order.command.SteeringWheelLeftComm:order.command.SteeringWheelLeftComm@1034bb5	init	class receive.component.SteeringWheelLeftRec:receive.component.SteeringWheelLeftRec@15f5897
class order.command.BrakeComm:order.command.BrakeComm@186d4c1	init	class receive.component.BrakeRec:receive.component.BrakeRec@f9f9d8
class order.command.IgnitionComm:order.command.IgnitionComm@87816d	init	class receive.component.IgnitionRec:receive.component.IgnitionRec@422ede
class order.command.ClutchComm:order.command.ClutchComm@93dcd	init	class receive.component.ClutchRec:receive.component.ClutchRec@b89838
class order.command.HangOutComm:order.command.HangOutComm@a83b8a	init	class receive.component.HangOutRec:receive.component.HangOutRec@dd20f6
class order.command.OilComm:order.command.OilComm@22c95b	init	class receive.component.OilRec:receive.component.OilRec@1d1acd3
order.step.CarStart	init	java.util.LinkedList
class receive.car.CarStart:receive.car.CarStart@a981ca	init	class order.step.CarStart:order.step.CarStart@8814e9
执行命令
class receive.car.CarStart	receive	receive.car.CarStart@a981ca
receive.car.CarStart	doReceive	class receive.car.CarStart
class order.step.CarStart	execute	order.step.CarStart@8814e9
class order.command.WearingSeatbeltComm	execute	order.command.WearingSeatbeltComm@1befab0
class receive.component.WearingSeatbeltRec	receive	receive.component.WearingSeatbeltRec@13c5982
class receive.component.WearingSeatbeltRec	doReceive	receive.component.WearingSeatbeltRec@13c5982
系安全带
class order.command.TurnSignalLeftComm	execute	order.command.TurnSignalLeftComm@c21495
class receive.component.TurnSignalLeftRec	receive	receive.component.TurnSignalLeftRec@1d5550d
class receive.component.TurnSignalLeftRec	doReceive	receive.component.TurnSignalLeftRec@1d5550d
左转向灯
class order.command.SteeringWheelLeftComm	execute	order.command.SteeringWheelLeftComm@1034bb5
class receive.component.SteeringWheelLeftRec	receive	receive.component.SteeringWheelLeftRec@15f5897
class receive.component.SteeringWheelLeftRec	doReceive	receive.component.SteeringWheelLeftRec@15f5897
左打方向盘
class order.command.BrakeComm	execute	order.command.BrakeComm@186d4c1
class receive.component.BrakeRec	receive	receive.component.BrakeRec@f9f9d8
class receive.component.BrakeRec	doReceive	receive.component.BrakeRec@f9f9d8
刹车
class order.command.IgnitionComm	execute	order.command.IgnitionComm@87816d
class receive.component.IgnitionRec	receive	receive.component.IgnitionRec@422ede
class receive.component.IgnitionRec	doReceive	receive.component.IgnitionRec@422ede
点火
class order.command.ClutchComm	execute	order.command.ClutchComm@93dcd
class receive.component.ClutchRec	receive	receive.component.ClutchRec@b89838
class receive.component.ClutchRec	doReceive	receive.component.ClutchRec@b89838
离合
class order.command.HangOutComm	execute	order.command.HangOutComm@a83b8a
class receive.component.HangOutRec	receive	receive.component.HangOutRec@dd20f6
class receive.component.HangOutRec	doReceive	receive.component.HangOutRec@dd20f6
挂挡
class order.command.OilComm	execute	order.command.OilComm@22c95b
class receive.component.OilRec	receive	receive.component.OilRec@1d1acd3
class receive.component.OilRec	doReceive	receive.component.OilRec@1d1acd3
给油

5.总结

可以看到上面的例子中new了非常多的对象。而且new出来的这些对象基本上都相同。
所以,能不能使用享元模式提高性能。

5.1 命令的享元工厂

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
package order.flyweight;

import java.util.HashMap;
import java.util.Map;

import order.abs.AbsCommand;

public class FlyWeightComm {

	private static Map<String, AbsCommand> map = new HashMap<String, AbsCommand>();
	
	private static final FlyWeightComm instance = new FlyWeightComm();
	
	private FlyWeightComm(){
		
	}
	
	public static FlyWeightComm getInstance(){
		return instance;
	}
	
	public static AbsCommand getAbsCommand(String comm){
		if(map.containsKey(comm)){
			return map.get(comm);
		} else {
			AbsCommand command = null;
			try {
				command = (AbsCommand)Class.forName("order.command."+comm).newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			map.put(comm, command);
			return command;
		}
	}
	
}

5.2 执行者的享元工厂

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
package receive.flyweight;

import java.util.HashMap;
import java.util.Map;

import receive.abs.AbsCar;

public class FlyWeightRec {

	private static Map<String, AbsCar> map = new HashMap<String, AbsCar>();
	
	private static final FlyWeightRec instance = new FlyWeightRec();
	
	private FlyWeightRec(){
		
	}
	
	public static FlyWeightRec getInstance(){
		return instance;
	}
	
	public static AbsCar getAbsCar(String recName){
		if(map.containsKey(recName)){
			return map.get(recName);
		} else {
			AbsCar absCar = null;
			try {
				absCar = (AbsCar)Class.forName("receive.component."+recName).newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			map.put(recName, absCar);
			return absCar;
		}
	} 
	
}

结果完全相同。

但是我们在增加一种操作:
加速:
给油、离合、挂挡、给油。
加的时候发现命令的集合这个角色的类的相似度非常的高,所以我们对命令的角色的类进行重构:抽取抽象类:

5.2.1抽象的命令的集合:

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
package order.step.abs;

import java.util.LinkedList;
import java.util.Queue;

import order.intf.IntfCommand;

public abstract class CarCommAbs implements IntfCommand{

	protected Queue<IntfCommand> step = new LinkedList<IntfCommand>();
	
	public CarCommAbs() {
	
		init();
		
	}
	
	protected abstract void init();
	
	@Override
	public void execute() {
		System.out.println(this.getClass() + "\texecute\t"
				+ this);
		IntfCommand command = step.poll();
		while(command != null){
			command.execute();
			command = step.poll();
		}
		
	}
	
}

5.2.2具体的命令的集合

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
package order.step.impl;

import order.flyweight.FlyWeightComm;
import order.step.abs.CarCommAbs;

/**
 * 车起步:
 * 
 * 系安全带
 * 左转向灯
 * 左转向
 * 刹车
 * 点火 
 * 离合
 * 挂挡
 * 给油
 *
 */
public class CarStartComm extends CarCommAbs{

	@Override
	protected void init(){
		
		step.add(FlyWeightComm.getAbsCommand("WearingSeatbeltComm"));
		step.add(FlyWeightComm.getAbsCommand("TurnSignalLeftComm"));
		step.add(FlyWeightComm.getAbsCommand("SteeringWheelLeftComm"));
		step.add(FlyWeightComm.getAbsCommand("BrakeComm"));
		step.add(FlyWeightComm.getAbsCommand("IgnitionComm"));
		step.add(FlyWeightComm.getAbsCommand("ClutchComm"));
		step.add(FlyWeightComm.getAbsCommand("HangOutComm"));
		step.add(FlyWeightComm.getAbsCommand("OilComm"));
		
		System.out.println(this.getClass().getName() + "\tinit\t"
				+ step.getClass().getName());
	}
	
}




package order.step.impl;

import order.flyweight.FlyWeightComm;
import order.step.abs.CarCommAbs;

public class CarAddComm extends CarCommAbs{

	@Override
	protected void init() {
		
		step.add(FlyWeightComm.getAbsCommand("OilComm"));
		step.add(FlyWeightComm.getAbsCommand("ClutchComm"));
		step.add(FlyWeightComm.getAbsCommand("HangOutComm"));
		step.add(FlyWeightComm.getAbsCommand("OilComm"));
		
	}

	
}

5.2.3 抽象的命令的发动者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package receive.car.abs;

import order.step.abs.CarCommAbs;
import receive.abs.AbsCar;

public abstract class CarRecAbs extends AbsCar{

	protected CarCommAbs carStart;

	public CarRecAbs() {

		init();
	}
	
	protected abstract void init(); 
	
	@Override
	protected void doReceive() {
		System.out.println(this.getClass().getName() + "\tdoReceive\t"
				+ this.getClass());
		carStart.execute();
	}

}

5.2.4 具体的命令的发动者

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
package receive.car.impl;

import order.step.impl.CarAddComm;
import receive.car.abs.CarRecAbs;

public class CarAddRec extends CarRecAbs{

	@Override
	protected void init() {
		carStart = new CarAddComm();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + carStart.getClass() + ":"
				+ carStart);
	}

}




package receive.car.impl;

import order.step.impl.CarStartComm;
import receive.car.abs.CarRecAbs;

/**
 * 车起步:
 * 
 * 系安全带 左转向灯 左转向 刹车 点火 离合 挂挡 给油
 *
 */
public class CarStartRec extends CarRecAbs {

	@Override
	protected void init() {
		carStart = new CarStartComm();
		System.out.println(this.getClass() + ":" + this
				+ "\tinit\t" + carStart.getClass() + ":"
				+ carStart);
	}

}

5.2.5 调用者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package client;

import receive.car.impl.CarAddRec;
import receive.car.impl.CarStartRec;

public class Main {

	public static void main(String[] args) {

		System.out.println("生成命令----起步");
		CarStartRec carStart = new CarStartRec();
		System.out.println("生成命令----加速");
		CarAddRec carAddRec = new CarAddRec();
		System.out.println("执行命令----加速");
		carStart.receive();
		System.out.println("执行命令----加速");
		carAddRec.receive();
	}

}

5.2.6 结果

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
生成命令----起步
class order.command.WearingSeatbeltComm:order.command.WearingSeatbeltComm@c2ea3f	init	class receive.component.WearingSeatbeltRec:receive.component.WearingSeatbeltRec@a0dcd9
class order.command.TurnSignalLeftComm:order.command.TurnSignalLeftComm@b162d5	init	class receive.component.TurnSignalLeftRec:receive.component.TurnSignalLeftRec@1cfb549
class order.command.SteeringWheelLeftComm:order.command.SteeringWheelLeftComm@1820dda	init	class receive.component.SteeringWheelLeftRec:receive.component.SteeringWheelLeftRec@15b7986
class order.command.BrakeComm:order.command.BrakeComm@112f614	init	class receive.component.BrakeRec:receive.component.BrakeRec@1d9dc39
class order.command.IgnitionComm:order.command.IgnitionComm@111a3ac	init	class receive.component.IgnitionRec:receive.component.IgnitionRec@110b053
class order.command.ClutchComm:order.command.ClutchComm@19efb05	init	class receive.component.ClutchRec:receive.component.ClutchRec@723d7c
class order.command.HangOutComm:order.command.HangOutComm@a981ca	init	class receive.component.HangOutRec:receive.component.HangOutRec@8814e9
class order.command.OilComm:order.command.OilComm@743399	init	class receive.component.OilRec:receive.component.OilRec@e7b241
order.step.impl.CarStartComm	init	java.util.LinkedList
class receive.car.impl.CarStartRec:receive.car.impl.CarStartRec@167d940	init	class order.step.impl.CarStartComm:order.step.impl.CarStartComm@e83912
生成命令----加速
class receive.car.impl.CarAddRec:receive.car.impl.CarAddRec@1d8957f	init	class order.step.impl.CarAddComm:order.step.impl.CarAddComm@3ee284
执行命令----加速
class receive.car.impl.CarStartRec	receive	receive.car.impl.CarStartRec@167d940
receive.car.impl.CarStartRec	doReceive	class receive.car.impl.CarStartRec
class order.step.impl.CarStartComm	execute	order.step.impl.CarStartComm@e83912
class order.command.WearingSeatbeltComm	execute	order.command.WearingSeatbeltComm@c2ea3f
class receive.component.WearingSeatbeltRec	receive	receive.component.WearingSeatbeltRec@a0dcd9
class receive.component.WearingSeatbeltRec	doReceive	receive.component.WearingSeatbeltRec@a0dcd9
系安全带
class order.command.TurnSignalLeftComm	execute	order.command.TurnSignalLeftComm@b162d5
class receive.component.TurnSignalLeftRec	receive	receive.component.TurnSignalLeftRec@1cfb549
class receive.component.TurnSignalLeftRec	doReceive	receive.component.TurnSignalLeftRec@1cfb549
左转向灯
class order.command.SteeringWheelLeftComm	execute	order.command.SteeringWheelLeftComm@1820dda
class receive.component.SteeringWheelLeftRec	receive	receive.component.SteeringWheelLeftRec@15b7986
class receive.component.SteeringWheelLeftRec	doReceive	receive.component.SteeringWheelLeftRec@15b7986
左打方向盘
class order.command.BrakeComm	execute	order.command.BrakeComm@112f614
class receive.component.BrakeRec	receive	receive.component.BrakeRec@1d9dc39
class receive.component.BrakeRec	doReceive	receive.component.BrakeRec@1d9dc39
刹车
class order.command.IgnitionComm	execute	order.command.IgnitionComm@111a3ac
class receive.component.IgnitionRec	receive	receive.component.IgnitionRec@110b053
class receive.component.IgnitionRec	doReceive	receive.component.IgnitionRec@110b053
点火
class order.command.ClutchComm	execute	order.command.ClutchComm@19efb05
class receive.component.ClutchRec	receive	receive.component.ClutchRec@723d7c
class receive.component.ClutchRec	doReceive	receive.component.ClutchRec@723d7c
离合
class order.command.HangOutComm	execute	order.command.HangOutComm@a981ca
class receive.component.HangOutRec	receive	receive.component.HangOutRec@8814e9
class receive.component.HangOutRec	doReceive	receive.component.HangOutRec@8814e9
挂挡
class order.command.OilComm	execute	order.command.OilComm@743399
class receive.component.OilRec	receive	receive.component.OilRec@e7b241
class receive.component.OilRec	doReceive	receive.component.OilRec@e7b241
给油
执行命令----加速
class receive.car.impl.CarAddRec	receive	receive.car.impl.CarAddRec@1d8957f
receive.car.impl.CarAddRec	doReceive	class receive.car.impl.CarAddRec
class order.step.impl.CarAddComm	execute	order.step.impl.CarAddComm@3ee284
class order.command.OilComm	execute	order.command.OilComm@743399
class receive.component.OilRec	receive	receive.component.OilRec@e7b241
class receive.component.OilRec	doReceive	receive.component.OilRec@e7b241
给油
class order.command.ClutchComm	execute	order.command.ClutchComm@19efb05
class receive.component.ClutchRec	receive	receive.component.ClutchRec@723d7c
class receive.component.ClutchRec	doReceive	receive.component.ClutchRec@723d7c
离合
class order.command.HangOutComm	execute	order.command.HangOutComm@a981ca
class receive.component.HangOutRec	receive	receive.component.HangOutRec@8814e9
class receive.component.HangOutRec	doReceive	receive.component.HangOutRec@8814e9
挂挡
class order.command.OilComm	execute	order.command.OilComm@743399
class receive.component.OilRec	receive	receive.component.OilRec@e7b241
class receive.component.OilRec	doReceive	receive.component.OilRec@e7b241
给油

5.2.7 说明

这里命令的集合的实现不能放在享元的工厂中,虽然命令与命令的集合都实现了命令的接口,理论上把命令的集合放在享元的工厂中也不会报错。但是会有执行错误。
原因就是命令的集合在调用命令时的方法:

1
2
3
4
5
6
7
8
9
10
11
@Override
	public void execute() {
		System.out.println(this.getClass() + "\texecute\t"
				+ this);
		IntfCommand command = step.poll();
		while(command != null){
			command.execute();
			command = step.poll();
		}
		
	}

可以看到使用的是队列的弹出方法,这个方法具有两个操作:
1.返回队列头部的元素
2.删除当前队列头部的元素,并把头指向下一个元素

也就是说上面的这个方法破坏了数据,无法作为享元工厂的元数据。

那么必须要使用享元提高性能怎么办?
那就在上一层:我们这里的操作是起步,加速这一类的操作,更高一层的操作就是以起步,加速的操作作为原子操作的级别,在这一级别的享元工厂可以把起步、加速作为元数据。

但是命令的发动者的角色可以放在享元的工厂中:
因为发动者的方法没有破坏数据:

1
2
3
4
5
6
@Override
	protected void doReceive() {
		System.out.println(this.getClass().getName() + "\tdoReceive\t"
				+ this.getClass());
		carStart.execute();
	}

只是调用方法。
23种设计模式

本文由作者按照 CC BY 4.0 进行授权