设计模式之享元模式。
通过使用池的技术,有效减少了大量细粒度
的对象的重复生成。
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 总结
- 优点:大大减少相同对象的数量,内外部状态互相独立。
- 缺点:需要区分内外部状态,增加系统设计难度。
- 适用场景:一个系统有大量相同或者相似的对象,造成内存的大量耗费。