享元模式
定义
享元模式(Flyweight Pattern)是池技术的重要实现方式。
使用共享对象可以有效地支持大量的细粒度对象。
优缺点、应用场景
优点
可以大大减少应用程序创建对象的数量,降低程序内存占用。
缺点
提高了系统的复杂度,需要分离出享元对象的外部状态(key)和内部状态(对象属性),并且外部状态应该有可常量化的特性(如:String、int),否则导致系统的逻辑混乱
应用场景
- 大量相似的对象
- 享元对象应该具有相似的外部状态(对外标识的key的生成逻辑相同)
- 需要缓冲池的场景
代码模拟场景
从平家boy缓冲池中拣选一些boy进入地牢。。。
享元模式
UML图
抽象享元对象——PingjiaBoy
/*** 享元角色抽象 平家boy*/
public abstract class PingjiaBoy {/*** 提取对象池的KEY*/protected String key;/*** 名字*/private String name;/*** 职业*/private String job;/*** 权力*/private String power;public PingjiaBoy(String key) {this.key = key;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public String getPower() {return power;}public void setPower(String power) {this.power = power;}
}
享元对象示例——PingjiaBoyPool
/*** 享元角色实例 平家boy候选池*/
public class PingjiaBoyPool extends PingjiaBoy {public PingjiaBoyPool(String key) {super(key);}public String getKey() {return key;}public void setKey(String key) {this.key = key;}
}
享元工厂——PingjiaBoyFactory
/*** 享元工厂 黑暗♂地牢*/
public class PingjiaBoyFactory {/*** 创建一个boy的预备候选池*/private final static Map<String, PingjiaBoy> BOY_POOL = new HashMap<>();/*** 根据key挑选平家boy惩罚** @param key key* @return 平家boy*/public static PingjiaBoy getPingjiaBoy(String key) {PingjiaBoy result;// 如果池中没有这个boy,则添加if (!BOY_POOL.containsKey(key)) {System.out.println(key + " Take it boy...");result = new PingjiaBoyPool(key);BOY_POOL.put(key, result);} else {// 存在则直接拣♂选出来result = BOY_POOL.get(key);System.out.println(key + " Come on...");}return result;}
}
入口类方法
private static void takeItBoy() {for (int i = 0; i < 3; i++) {String color = "肤色" + i;for (int j = 0; j < 10; j++) {String key = color + "样貌" + j;PingjiaBoyFactory.getPingjiaBoy(key);}}PingjiaBoy pingjiaBoy = PingjiaBoyFactory.getPingjiaBoy("肤色2样貌8");System.out.println(pingjiaBoy);
}
结果
参考书籍
秦小波《设计模式之禅》