• Java设计模式----享元模式(FlyWeight)


    1.  享元模式定义:

         享元模式是池技术的重要实现原理,定义如下:使用共享对象可以有效的支持大量的细粒度对象

        内部状态:存储在享元对象内部不随外部环境改变可以共享出来的信息

        外部状态:外部状态是对象得以依赖的一个标记,是随外部环境改变而变化、不可以共享的状态

    2.  享元模式的角色名称:

          a.  抽象享元角色

          简单地说,就是一个产品的抽象类,它同时定义了对象的内部状态和外部状态,以及接口和实现

         b. 具体的享元对象

         具体的产品类,实现了抽象产品类定义的业务

        c.  享元工厂

        提供一个池容器,同时提供从池中获取对象的方法

    3.  享元模式通用示例代码:

    抽象享元角色类:

    public abstract class FlyWeight {
        
    	//内部状态
    	private String intrinsic; 
    	private String name;
    	//外部状态
    	protected final String extrinsic;
    	
    	//要求享元角色必须接受外部状态
    	public FlyWeight(String extrinsic) {
    		this.extrinsic=extrinsic;
    	}
    	
    	//定义业务操作
    	public abstract void  operator();
        
    	//内部状态的getter/setter
    	public String getIntrinsic() {
    		return intrinsic;
    	}
    
    	public void setIntrinsic(String intrinsic) {
    		this.intrinsic = intrinsic;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    		
    }
    抽象享元角色类一般是一个抽象类,一般要把外部状态和内部状态定义出来,避免子类随意的扩展。

    具体的享元角色类:

    public class FlyWeight1 extends FlyWeight{
       
    	public FlyWeight1(String extrinsic) {
    		super(extrinsic);
    	}
    
    	@Override
    	public void operator() {
    		
    		System.out.println("业务操作方法...内部状态是:"+super.getIntrinsic());
    		
    	}
    }
    享元工厂类:

    public class FlyWeightFactory {
       
    	private static HashMap<String,FlyWeight> pool=new HashMap<String,FlyWeight>();
    	
    	public static  FlyWeight getInstance(String key){
    		//需要返回的对象
    		FlyWeight flyWeight=null;
    		//如果池中存在该对象,直接获取返回
    		if(pool.containsKey(key)){
    			System.out.println(key+"-----池中存在,直接从对象池中取得");
    			flyWeight=pool.get(key);
    		}else{
    			//池中不存在此对象,根据外部状态新建一个对象返回
    			System.out.println(key+"-----池中不存在,建立对象并放到对象池中");
    			flyWeight=new FlyWeight1(key);
    			//放置到池中
    			pool.put(key, flyWeight);
    		}
    		return flyWeight;
    	}
    	
    	/**
    	 * 初始化对象池
    	 * @param size
    	 */
    	public static void initObjectPool(int size){
    		for (int i = 0; i <= size; i++) {
    			FlyWeightFactory.getInstance("对象"+i);
    		}
    	}
    }
    测试类:

    public class Test {
       
    	public static void main(String[] args) {
    		//初始化对象池
    		FlyWeightFactory.initObjectPool(4);
    		FlyWeight flyWeight=FlyWeightFactory.getInstance("对象1");
    		flyWeight.setIntrinsic("这是单独设置的内部状态!");
    		flyWeight.operator();
    	}
    }
    结果:

    对象0-----池中不存在,建立对象并放到对象池中
    对象1-----池中不存在,建立对象并放到对象池中
    对象2-----池中不存在,建立对象并放到对象池中
    对象3-----池中不存在,建立对象并放到对象池中
    对象4-----池中不存在,建立对象并放到对象池中
    对象1-----池中存在,直接从对象池中取得
    业务操作方法...内部状态是:这是单独设置的内部状态!
    4.   享元模式的优点和缺点

          享元模式是可以大大减少应用程序创建对象的时间,降低程序内存的占用,增强程序的性能,同时它也大大加大了程序的复杂度,因为需要分离外部状态和内部状态。

    5.  享元模式的使用场景

              在如下场景中则可以选择使用享元模式。

    ● 系统中存在大量的相似对象。

    ● 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。

    ● 需要缓冲池的场景。

    6.  享元模式的线程安全问题:

         由于使用的是共享对象,所以很可能会出现2个线程共用一个对象并且同时修改的问题,这样就会出现线程安全问题。为了尽可能避免这个问题,要尽量的加大对象池中对象的数量,并且对于外部状态,最好可以使用多个字符串的组合来确定key值(即对象池中,一个对象对应一个key值)







  • 相关阅读:
    孤荷凌寒自学python第114天区块链028以太坊智能合约007
    孤荷凌寒自学python第113天区块链027以太坊智能合约006
    孤荷凌寒自学python第112天认识区块链026
    孤荷凌寒自学python第111天区块链025eth智能合约004
    孤荷凌寒自学python第110天区块链024ETH智能合约003
    孤荷凌寒自学python第109天区块链023初识eth智能合约002
    孤荷凌寒自学python第108天区块链022之eth智能合约001
    孤荷凌寒自学python第106天认识区块链020
    孤荷凌寒自学python第105天认识区块链019
    Upenn树库的基本框架
  • 原文地址:https://www.cnblogs.com/elgin-seth/p/5293763.html
Copyright © 2020-2023  润新知