享元模式
享元模式的目的在于运用共享技术,使得一些细粒度的对象可以共享。
多食用细粒度的对象,以便于重用或者重构。
定义
使用共享对象可以有效地支持大量的细粒度的对象。
大量的细粒度对象,需要把对象的共有属性提取出来,做为内部状态,剩余的非共有做为外部状态。
内部状态:可以共享出来的信息,存储在襄垣对象内部,并且不会随着环境的改变而改变。
外部状态:对象得以依赖的一个标记,是随着环境的改变而改变的,不可以共享的状态。

实现
Flyweight
抽象享元角色,产品抽象类,同时定义出对象的外部状态和内部状态的接口或者实现。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | public abstract  class Flyweight{private String instrinsic;
 protected final String extrinsic;
 
 public Flyweight(String extrinsic){
 this.extrinsic = extrinsic;
 }
 
 public abstract void operate();
 
 public String getInstrinsic(){
 return this.instrinsic;
 }
 
 public void setInstrinsic(String instrinsic){
 this.instrinsic = instrinsic;
 }
 }
 
 | 
ConcreteFlyweight
具体享元角色,实现抽象角色的定义业务,该角色中需要注意的是内部状态处理应该与环境无关。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | 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(){
 
 }
 }
 
 | 
unsharConcreteFlyweight
不可共享的享元角色
不存在外部状态或者安全要求不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。
FlyweightFactory
享元工厂,构造一个池容器,同时提供从池中获得对象的方法。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | public class FlyweightFactory{private static HashMap<String, Flyweight> pool = new HashMap<>();
 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;
 }
 }
 
 | 
应用
优点
可以减少应用程序创建的对象,降低程序内存的占用,增强程序的性能。
缺点
提高了程序的复杂性,需要分离出内部状态和外部状态,而且外部状态具有固话特征,不能随着内部状态的改变而改变。
扩展
- 线程安全的问题
 创建的对象尽量多,多到满足业务对象为止。
- 性能平衡
 外部状态最好以基本类型为标志,如String, Int等可以大幅提升效率。