享元模式/Flyweight模式/对象结构型/设计模式

flyweight 享元模式(对象结构型)

Flyweight在拳击比赛中指最轻量级,即“蝇量级”或“雨量级”,这里选择使用“享元模式”的意译,是因为这样更能反映模式的用意。享元模式是对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象。

意图

运用共享技术有效地支持大量细粒度的对象。关键字:对象共享

动机

Flyweight模式描述了如何共享对象,降低内存消耗和运行开销。Flyweight是一个共享对象,对象有内部状态和外部状态。
内部状态存于享元中,包含独立于场景的信息;
外部状态取决于场景,非共享。

适用场景

  1. 程序适用了大量对象,并造成了很大的存储开销
  2. 对象的大多数状态都可以变为外部状态
  3. 删除外部状态后,可以用相对较少的共享对象取代原对象们

享元模式要素 享元接口+享元+享元工厂

  1. Flyweight接口,规定享元需要实现的方法,外部状态,可变部分
  2. ConcreteFlyweight,具体享元对象,为内部状态提供存储空间,实现享元接口,为外部状态提供入口
  3. FlyweightFactory,享元工厂,创建和管理具体享元角色。

简单享元模式代码

interface Flyweight{
    void fly(Object externalState);
}

class ConcreteFlyweight implements Flyweight{
    private Object innerState=null;
	
	//内部状态存储
	public ConcreteFlyweight(Object innerState){
        this.innerState = innerState;
    }
	
	//外部状态,改变行为
	@Override
	public void fly(Object externalState) {
		// do sth
	}
	
}

 class FlyweightFactory {
    private Map<Object,Flyweight> files = new HashMap<Object,Flyweight>();
    
    public Flyweight factory(Object state){
        //从工厂中取出缓存的享元,不存在则创建,并放入缓存
        Flyweight fly = files.get(state);
        if(fly == null){
            fly = new ConcreteFlyweight(state);
            files.put(state, fly);
        }
        return fly;
    }
}

组合式的享元模式

将单独可共享的具体享元对象,进行各种组合,并提供访问接口。

interface Flyweight{
    void fly(Object externalState);
}

class ConcreteFlyweight implements Flyweight{
	private Object innerState=null;
	public ConcreteFlyweight(Object innerState){
        this.innerState = innerState;
    }
	@Override
	public void fly(Object externalState) {
		// do sth
	}
	
}

//组合享元,提供一组享元的组合,并提供享元接口
class CompositeConcreteFlyweight implements Flyweight{
	private List<Flyweight> flyweights=new ArrayList<>();
    
    //组合享元组,添加单享元
	public void add(Flyweight flyweight){
		flyweights.add(flyweight);
    }
    
    //享元组,外边状态接口方法
	@Override
	public void fly(Object externalState) {
		for (Flyweight flyweight : flyweights) {
			flyweight.fly(externalState);
		}
	}
}
    
//享元工厂,提供组合享元和单独享元的获取方法
 class FlyweightFactory {
    private Map<Object,Flyweight> files = new HashMap<Object,Flyweight>();
    
   //获取享元组 
    public Flyweight factory(List<Object> compositeState){
    	CompositeConcreteFlyweight compositeFly = new CompositeConcreteFlyweight();
        for(Object state : compositeState){
            compositeFly.add(factory(state));
        }
        
        return compositeFly;
    }
   
    //获取单享元
    public Flyweight factory(Object state){
        Flyweight fly = files.get(state);
        if(fly == null){
            fly = new ConcreteFlyweight(state);
            files.put(state, fly);
        }
        return fly;
    }
}

经典应用

文档编辑器,每个字符,都是一个享元对象,这使得文档编辑器运行很快。
还有就是JDK中的String对象,相同的字符串,地址相当(可以用==判断),所以每个字符串都是常量,并且是享元。

参考

《设计模式》
相关博客

posted @ 2016-09-05 20:25  toto怎么会喝醉  阅读(175)  评论(0编辑  收藏  举报