• 享元模式/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对象,相同的字符串,地址相当(可以用==判断),所以每个字符串都是常量,并且是享元。

    参考

    《设计模式》
    相关博客



    I am a slow walker, but I never walk backwards.



  • 相关阅读:
    如何用伪类画出一个三角形
    关于昨天遇到题目的一点随笔
    opacity与rgba
    选择框脚本_移动/重排选项 P435
    文字等宽
    CSS3风骚渐变
    表单序列化 P436
    选择框脚本_添加/删除选项 P434
    选择框脚本_用事件选中选项,获取选中项信息 P432
    文本框组脚本_自动切换焦点“例如加区号和分机号的电话号码文本框组” P426
  • 原文地址:https://www.cnblogs.com/lknny/p/5843510.html
Copyright © 2020-2023  润新知