设计模式之享元模式(卷十一)

设计模式之享元模式。

通过使用池的技术,有效减少了大量细粒度的对象的重复生成。

0x00 组织结构

  • Flyweight:抽象享元类,声明了可以想外界提供内部状态的方法,同时还可以设置外部状态。
  • ConcreteFlyweight:具体享元类,通常和单例模式组合使用。
  • UnsharedConcreteFlyweight(非共享具体享元类):并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。
  • FlyweightFactory:享元池,享元池一般设计为一个存储“键值对”的集合,可以结合工厂模式进行设计。

0x01 示例

以组装PC为例,其中CPU充当内部状态,Computer充当外部状态。

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
271
272
273
274
package com.kkk.pattern.flyweight;

/**
* 充当享元类
* Created by z3jjlzt on 2018/1/10.
*/

public abstract class CPU {

//获取内部状态
public abstract String getCPUName();

//注入外部状态
public void setComputer(Computer computer) {
System.out.println("把型号为 " + getCPUName() + "的cpu安装在型号为 " + computer + "的电脑上");
}
}

/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/

public class AMDCPU extends CPU {

private AMDCPU() {}

private static class Instance{
private static final AMDCPU cpu = new AMDCPU();
}

public static AMDCPU getInstance() {
return Instance.cpu;
}

@Override
public String getCPUName() {
return "AMD";
}
}

/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/

public class IntelCPU extends CPU {

private IntelCPU() {}

private static class Instance{
private static final IntelCPU cpu = new IntelCPU();
}

public static IntelCPU getInstance() {
return Instance.cpu;
}

@Override
public String getCPUName() {
return "Intel";
}
}

/**
* 充当外部状态
* Created by z3jjlzt on 2018/1/10.
*/

public class Computer {
private String name;

public Computer(String name) {
this.name = name;
}

@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Computer{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}

import java.util.HashMap;

/**
* 充当共享池
* Created by z3jjlzt on 2018/1/10.
*/

public class CPUFactory {

private static HashMap<String, CPU> fpool = new HashMap<>();

private CPUFactory() {
}

private static class Instance {
private static final CPUFactory cf = new CPUFactory();
}

public static CPUFactory getInstance() {
return Instance.cf;
}

public static CPU getCPU(String type) {
if (null == fpool.get(type)) {
switch (type) {
case "AMD":
fpool.put("AMD", AMDCPU.getInstance());
break;
case "Intel":
fpool.put("Intel", IntelCPU.getInstance());
break;
default:
break;
}
}
return fpool.get(type);
}
}

/**
* Created by z3jjlzt on 2018/1/10.
*/

public class Client {
public static void main(String[] args) {
CPUFactory cpuFactory = CPUFactory.getInstance();
CPU amd1 = cpuFactory.getCPU("AMD");
CPU amd2 = cpuFactory.getCPU("AMD");
CPU intel1 = cpuFactory.getCPU("Intel");
System.out.println(amd1 == amd2);
System.out.println(amd1 == intel1);
amd1.setComputer(new Computer("新华同方"));
intel1.setComputer(new Computer("华硕"));
}
}
结果:
package com.kkk.pattern.flyweight;

/**
* 充当享元类
* Created by z3jjlzt on 2018/1/10.
*/

public abstract class CPU {

//获取内部状态
public abstract String getCPUName();

//注入外部状态
public void setComputer(Computer computer) {
System.out.println("把型号为 " + getCPUName() + "的cpu安装在型号为 " + computer + "的电脑上");
}
}

/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/

public class AMDCPU extends CPU {

private AMDCPU() {}

private static class Instance{
private static final AMDCPU cpu = new AMDCPU();
}

public static AMDCPU getInstance() {
return Instance.cpu;
}

@Override
public String getCPUName() {
return "AMD";
}
}

/**
* 充当具体享元
* Created by z3jjlzt on 2018/1/10.
*/

public class IntelCPU extends CPU {

private IntelCPU() {}

private static class Instance{
private static final IntelCPU cpu = new IntelCPU();
}

public static IntelCPU getInstance() {
return Instance.cpu;
}

@Override
public String getCPUName() {
return "Intel";
}
}

/**
* 充当外部状态
* Created by z3jjlzt on 2018/1/10.
*/

public class Computer {
private String name;

public Computer(String name) {
this.name = name;
}

@Override
public String toString() {
final StringBuffer sb = new StringBuffer("Computer{");
sb.append("name='").append(name).append('\'');
sb.append('}');
return sb.toString();
}
}

import java.util.HashMap;

/**
* 充当共享池
* Created by z3jjlzt on 2018/1/10.
*/

public class CPUFactory {

private static HashMap<String, CPU> fpool = new HashMap<>();

private CPUFactory() {
}

private static class Instance {
private static final CPUFactory cf = new CPUFactory();
}

public static CPUFactory getInstance() {
return Instance.cf;
}

public static CPU getCPU(String type) {
if (null == fpool.get(type)) {
switch (type) {
case "AMD":
fpool.put("AMD", AMDCPU.getInstance());
break;
case "Intel":
fpool.put("Intel", IntelCPU.getInstance());
break;
default:
break;
}
}
return fpool.get(type);
}
}

/**
* Created by z3jjlzt on 2018/1/10.
*/

public class Client {
public static void main(String[] args) {
CPUFactory cpuFactory = CPUFactory.getInstance();
CPU amd1 = cpuFactory.getCPU("AMD");
CPU amd2 = cpuFactory.getCPU("AMD");
CPU intel1 = cpuFactory.getCPU("Intel");
System.out.println(amd1 == amd2);
System.out.println(amd1 == intel1);
amd1.setComputer(new Computer("新华同方"));
intel1.setComputer(new Computer("华硕"));
}
}
结果:
true
false
把型号为 AMD的cpu安装在型号为 Computer{name='新华同方'}的电脑上
把型号为 Intel的cpu安装在型号为 Computer{name='华硕'}的电脑上

0xff 总结

  • 优点:大大减少相同对象的数量,内外部状态互相独立。
  • 缺点:需要区分内外部状态,增加系统设计难度。
  • 适用场景:一个系统有大量相同或者相似的对象,造成内存的大量耗费。