搬砖小弟
设计模式-享元模式
2019-06-30 / 3 min read

定义

Use sharing to support large numbers of fine-grained objects efficiently.(使用共享对象可有效地支持大量的细粒度的对象。)

UML

代码实现

public abstract class Flyweight {
     //内部状态
     private String intrinsic;
     //外部状态
     protected final String Extrinsic;
     //要求享元角色必须接受外部状态
     public Flyweight(String _Extrinsic){
             this.Extrinsic = _Extrinsic;
     }
     //定义业务操作
     public abstract void operate();
     //内部状态的getter/setter
     public String getIntrinsic() {
             return intrinsic;
     }
     public void setIntrinsic(String intrinsic) {
             this.intrinsic = intrinsic;
     }
}
public class ConcreteFlyweight1 extends Flyweight{
     //接受外部状态
     public ConcreteFlyweight1(String _Extrinsic){
             super(_Extrinsic);
     }
     //根据外部状态进行逻辑处理
     public void operate(){
             //业务逻辑
     }
}
public class ConcreteFlyweight2 extends Flyweight{
     //接受外部状态
     public ConcreteFlyweight2(String _Extrinsic){
             super(_Extrinsic);
     }
     //根据外部状态进行逻辑处理
     public void operate(){
             //业务逻辑
     }
}
public class FlyweightFactory {
     //定义一个池容器
     private static  HashMap<String,Flyweight> pool= new HashMap<String,Flyweight>();
     //享元工厂
     public static Flyweight getFlyweight(String Extrinsic){
             //需要返回的对象
             Flyweight flyweight = null;
             //在池中没有该对象
             if(pool.containsKey(Extrinsic)){
                     flyweight = pool.get(Extrinsic);
             }else{
                     //根据外部状态创建享元对象
                     flyweight = new ConcreteFlyweight1(Extrinsic);
                     //放置到池中
                     pool.put(Extrinsic, flyweight);
             }
             return flyweight;
     }
}

享元模式的优点与缺点

享元模式是一个非常简单的模式,它可以大大减少应用程序创建的对象,降低程序内存的占用,增强程序的性能,但它同时也提高了系统复杂性,需要分离出外部状态和内部状态,而且外部状态具有固化特性,不应该随内部状态改变而改变,否则导致系统的逻辑混乱。

享元模式的使用场景

  • 系统中存在大量的相似对象。
  • 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。
  • 需要缓冲池的场景。
  • 应用不根据对象的identity

JDK中Flyweight模式

  • java.lang.Integer#valueOf(int) (also on Boolean, Byte, Character, Short and Long)