享元模式
定义
享元模式(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);
}
结果
参考书籍
秦小波《设计模式之禅》