享元模式
意图
运用共享技术有效地支持大量细粒度的对象。
享元模式的本质是分离与共享 : 分离变与不变,并且共享不变。
适用性
1、系统中有大量对象,这些对象消耗大量内存;
2、这些对象的状态大部分可以外部化(注意划分外部状态和内部状态,否则可能会引起线程安全问题)。
如 Java 中的String,使用字符串缓存池,以及数据库连接池等。
扑克牌:需要确定需求场景是否适用
- 花色4,数字13,供52个实例对象;
- Card基类,4种花色子类,数字作为外部状态传入,只需要4个对象。
类图
在享元模式中可以共享的相同内容称为 内部状态(Intrinsic State),而那些需要外部环境来设置的不能共享的内容称为 外部状态(Extrinsic State)。
- 抽象享元(Flyweight):是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
- 具体享元(Concrete Flyweight):实现抽象享元角色中所规定的接口。
- 非享元(Unsharable Flyweight):是不可以共享的外部状态,它以参数的形式注入具体享元的相关方法中。
- 享元工厂(Flyweight Factory):负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
优缺点
优点:大大减少对象的创建,降低系统的内存,使效率提高。
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,而且外部状态具有固有化的性质,不应该随着内部状态的变化而变化,否则会造成系统的混乱。