参考自:https://blog.csdn.net/justloveyou_/article/details/55045638
存在的意义:面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式正是为解决这一类问题而诞生的。
内部状态(Intrinsic State):在享元模式中可以共享的相同内容
外部状态(Extrinsic State):需要外部环境来设置的不能共享的内容
在实际使用中,能够共享的内部状态是有限的,因此享元对象一般都设计为较小的对象,它所包含的内部状态较少,这种对象也称为细粒度对象。
由于 享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种 对象结构型模式。
模式结构:
单纯享元模式:在单纯享元模式中,所有的享元对象都是可以共享的,即所有抽象享元类的子类都可共享,不存在非共享具体享元类。
步骤一:建立一个抽象享元接口
//抽象享元角色类 public interface FlyWeight { //一个示意性方法,参数externalState是外蕴状态 void action(String externalState); }
步骤二:建立具体享元角色类
//具体享元角色类 public class ConcreteFlyWeight implements FlyWeight { //内蕴状态 private String name; //构造函数,内蕴状态作为参数传入 public ConcreteFlyWeight(String name) { this.name=name; } // 外蕴状态 externalState作为参数传入方法中,改变方法的行为,但是并不改变对象的内蕴状态name。 public void action(String externalState) { System.out.println(" 内蕴状态= " + this.name); System.out.println("外蕴状态 = " + externalState); } }
步骤三:建立一个享元工厂
//享元工厂角色类 public class FlyWeightFactory { private static final Logger log=LoggerFactory.getLogger(FlyWeightFactory.class); private static ConcurrentHashMap<String,FlyWeight> allFlyWeight=new ConcurrentHashMap<String,FlyWeight>(); public static FlyWeight getFlyWeight(String name) { if(allFlyWeight.get(name)==null) { synchronized(allFlyWeight) { if(allFlyWeight.get(name)==null) { System.out.println("实例名不存在,执行创建"); FlyWeight flyweight=new ConcreteFlyWeight(name); System.out.println("创建完成"); allFlyWeight.put(name, flyweight); } } } return allFlyWeight.get(name); } }
步骤四:测试
public class Test { public static void main(String[] args) { FlyWeightFactory factory=new FlyWeightFactory(); //申请三个享元对象A,B,B(但是实际创建只有两个) FlyWeight fly=factory.getFlyWeight("A"); fly.action("创建一个对象A"); fly=factory.getFlyWeight("B"); fly.action("创建一个对象B"); fly=factory.getFlyWeight("B"); fly.action("创建一个对象B"); } }
复合享元模式:将一些单纯享元使用组合模式加以组合,可以形成复合享元对象,这样的复合享元对象本身不能共享,但是它们可以分解成单纯享元对象,而后者则可以共享。
步骤一:建立抽象享元接口
//抽象享元角色类 public interface FlyWeight { //一个示意性方法,参数externalState是外蕴状态 void action(String externalState); }
步骤二:建立单纯具体享元角色类
//具体享元角色类 public class ConcreteFlyWeight implements FlyWeight { //内蕴状态 private String name; //构造函数,内蕴状态作为参数传入 public ConcreteFlyWeight(String name) { this.name=name; } // 外蕴状态 externalState作为参数传入方法中,改变方法的行为,但是并不改变对象的内蕴状态name。 public void action(String externalState) { System.out.println(" 内蕴状态= " + this.name); System.out.println("外蕴状态 = " + externalState); } }
步骤二:建立复合具体享元角色类
public class ConcreteCompositeFlyweight implements FlyWeight { private Map<String,FlyWeight> map=new HashMap<String,FlyWeight>(); //增加一个新的单纯享元对象到聚集中 public void add(String name,FlyWeight fly) { map.put(name, fly); } @Override public void action(String externalState) { FlyWeight fly = null; for(Object o:map.keySet()) { fly=map.get(o); fly.action("执行-----(外蕴状态)"); } } }
步骤三:建立享元工厂
//享元工厂角色类 public class FlyWeightFactory { private static ConcurrentHashMap<String,FlyWeight> allFlyWeight=new ConcurrentHashMap<String,FlyWeight>(); //复合享元工厂方法(接收的是一个List集合参数的内蕴状态(键),遍历来get到对应的享元对象) public FlyWeight getCompositeFlyWeight(List<String> compositestate) { ConcreteCompositeFlyweight compository=new ConcreteCompositeFlyweight(); for(String state:compositestate) { compository.add(state, this.getFlyWeight(state)); } return compository; } //单纯享元工厂方法 public static FlyWeight getFlyWeight(String name) { if(allFlyWeight.get(name)==null) { synchronized(allFlyWeight) { if(allFlyWeight.get(name)==null) { System.out.println("实例名不存在,执行创建"); FlyWeight flyweight=new ConcreteFlyWeight(name); System.out.println("创建完成"); allFlyWeight.put(name, flyweight); } } } return allFlyWeight.get(name); } }
步骤四:测试
public class Test { public static void main(String[] args) { List<String> compositestate=new ArrayList<String>(); compositestate.add("A"); compositestate.add("B"); compositestate.add("C"); compositestate.add("C"); FlyWeightFactory flyFactory=new FlyWeightFactory(); FlyWeight compositeFly1= flyFactory.getCompositeFlyWeight(compositestate); FlyWeight compositeFly2= flyFactory.getCompositeFlyWeight(compositestate); compositeFly1.action("复合享元模式-----"); System.out.println("----------"); System.out.println("复合享元对象是否共享对象:"+(compositeFly1==compositeFly2)); String state="hello"; FlyWeight fly1=flyFactory.getFlyWeight(state); FlyWeight fly2=flyFactory.getFlyWeight(state); System.out.println("单纯享元对象是否共享对象:"+(fly1==fly2)); } }