亨元模式
使用共享对象可以有效地支持大量细粒度的对象
亨元模式以共享的方式高效地支持大量的细粒度对象。亨元对象能做到共享的关键是区分内部状态(Internal State)和外部状态(External State)。
内部状态是存储在亨元对象内部的、可以共享的信息,并且不会随环境改变而变化。
外部状态是岁环境改变而改变且不可以共享的状态。亨元对象的外部状态必须由客户端保存,并在亨元对象创建之后,在需要的时候传入到亨元对象内部。
亨元模式角色
- 抽象亨元(Flyweight)角色:该角色对亨元类进行抽象,需要外部状态的操作可以通过参数形式将外部状态传入;
- 具体亨元(ConcreteFlyweight)角色:该角色实现抽象亨元定义的业务,主要亨元对象的内部状态必须与环境无关,从而使亨对象可以在内部共享;
- 亨元工厂(FlyWeightFactory)角色:该角色就是构造一个池容器,负责创建和管理亨元角色,并且提供从池容器中获得对象的方法,保证亨元对象可以被系统适当的共享。当一个客户端对象请求一个亨元对象时,亨元对象工厂角色会检查系统中是否已经存在一个符合的要求的亨元对象,如果存在则提供整个已有的亨元对象,否则创建一个合适的亨元对象。
亨元模式的优缺点
- 大幅减少内存中对象的数量,降低程序内存的占用,提高性能。但是,相应付出代价也很高;
- 亨元模式增加了系统的复杂性,需要分出外部状态和内部状态,而且内部状态固化特性,不应该随外部状态改变而改变,则使得程序的逻辑复杂化;
- 亨元模式将亨元对象的状态外部化,而读取外部状态使得运行时间长。
使用场景
- 系统中有大量的相似对象,这些对象占用大量的内存;
- 细粒度的对象都具备接近的外部状态,而且内部状态和环境无关,即对象没有特定身份;
- 需要缓冲池的场景。
<span style="font-size:18px;">public interface Flyweight {
//一个示意性方法,参数state是外蕴状态
public void operation(String state);
}</span>
<span style="font-size:18px;">public class FlyweightFactory {
private Map<Character,Flyweight> pool= new HashMap<Character,Flyweight>();
/**
* 单纯享元工厂方法
*/
public Flyweight factory(Character state){
//先从缓存中查找对象
Flyweight fly = pool.get(state);
if(fly == null){
//如果对象不存在则创建一个新的Flyweight对象
fly = new ConcreteFlyweight(state);
//把这个新的Flyweight对象添加到缓存中
pool.put(state, fly);
}
return fly;
}
}</span>