享元模式Flyweight
运用共享技术有效的支持大量细粒度的对象
FlyWeightFactory:享元工厂类,负责创建于管理享元对象,持有一个享元对象集合
FlyWeight:抽象享元类,抽象的产品同时定义外部状态接口或实现
ConcreteFlyWeight:具体享元类,具体产品类
UnShareConcreteFlyWeight:不可共享角色
内部状态与外部状态:
内部:不会碎环境改变的共享部分
外部: 随环境改变而改变的
内部状态存储于Flyweight,包含独立于场景的信息(共享)
外部状态取决于 Flyweight场景,根据场景而变化(非共享)
内部状态存储在ConcreteFlyweight中,外部状态由由用户通过参数传入,故内部状态一般由构造方法赋值,而外部状态提供给外部一个操作方法
各种池技术都是其应用,如String字符串常量池,缓冲出,数据库连接池
使用场景
一个程序产生大量对象,这些对象造成过大的存储开销
大多数状态可以为外部状态。
享元模式可以避免大量非常相似类的开销。避免生成大量细粒度的类实例来表示数据。细粒度的对象都具备较接近的外部状态,如果能把这些外部状态移到类实例的外面,在方法调用时将它们传递进来,就可以通过共享大幅度地减少单个实例的数目。
实例代码
FlyWeight:设置外部状态的抽象方法
public interface FlyWeight {
void operationExternal(String ExternalState);
}
ConcreteFlyWeight:
内部状态通过构造方法设置,实现外部状态设置方法
public class ConcreteFlyWeight implements FlyWeight{
private String internalState;
private String externalState;
public ConcreteFlyWeight(String internalState){
this.internalState = internalState;
}
@Override
public void operationExternal(String externalState) {
this.externalState = externalState;
}
@Override
public String toString() {
return "ConcreteFlyWeight{" +
"InternalState='" + internalState + '\'' +
", ExternalState='" + externalState + '\'' +
'}';
}
}
FlyWeightFactory:
Fly创建工厂,只有内部状态不同时,才创建新的对象
public class FlyWeightFactory {
private HashMap<String,FlyWeight> map = new HashMap<>();
public FlyWeight getFlyWeight(String key){
FlyWeight flyWeight = map.get(key);
if (flyWeight != null) {
return flyWeight;
}else {
flyWeight = new ConcreteFlyWeight(key);
map.put(key,flyWeight);
return flyWeight;
}
}
public int getCount(){
return map.size();
}
}
测试
public class Test {
public static void main(String[] args) {
FlyWeightFactory factory = new FlyWeightFactory();
FlyWeight f1 = factory.getFlyWeight("内部状态1");
FlyWeight f2 = factory.getFlyWeight("内部状态2");
f1.operationExternal("外部状态1");
System.out.println(f1.toString());
f1.operationExternal("外部状态2");
System.out.println(f1.toString());
f2.operationExternal("外部状态1");
System.out.println(f1.toString());
f2.operationExternal("外部状态2");
System.out.println(f1.toString());
System.out.println("共有两个实例"+factory.getCount());
}
}