前言
本文谈谈享元模式。
正文
概念
享元模式属于结构型模式,它主要是缓存重复的对象,以减少内存的消耗,这些相同的对象往往需要重复的使用,如果不对其进行缓存,可能会导致内存溢出。那享元模式一般配合工厂模式一起使用。
常见的应用场景有Java中的String,在创建String时判断缓存池里是否有这个字符串,有的话直接返回,没有才进行创建。
实现
享元模式中有以下几个角色:
- 抽象享元类(Flyweight):接口或者抽象类,声明公共方法。
- 具体享元类(ConcreteFlyweight):实现抽象享元类,结合单例模式提供唯一的对象。
- 享元工厂类(FlyweightFactory):用来创建及管理享元对象,可以参考工厂模式。
这里我们举个简单例子,一般商店里的物品不止一样,那么我们可以把同一个名称的商品作为共享的。
我们创建抽象接口FlyWeight
1 | public interface FlyWeight { |
接着我们可以创建商品类
1 | public class Item implements FlyWeight{ |
创建工厂类:
1 | public class FlyWeightFactory { |
那么客户端调用也很简单,商品从工厂类中获取即可
1 | public class Client { |
那以上例子还可以继续细化,比如Item类作为抽象类,而具体商品则继承它,那具体商品就可以有更多的属性,比如价格,批次等等。那在工厂类添加的时候可能需要根据传入名称来创建类,具体可以使用反射机制,这里就不再展开。
总而言之,享元模式中共享的对象是同一个,实现这个模式常常结合工厂模式,单例模式来使用,需要注意的是在多线程中需要使用线程安全的容器来存储对象。
优缺点
享元模式优点很明显,可以减少重复对象的创建,减低内存使用率。
那缺点可能就是需要区分外部状态与内部状态,内部状态不随环境改变,可共享,外部状态岁环境改变,不能共享。也就是上文例子中name作为外部状态可改变,如果再添加一个无法更改的属性比如价格,那么就是内部状态,无法被更改。
所以享元模式一定程度上增加了系统的复杂性。