享元模式的原理和实现都很简单,但是应用场景却相对狭窄,它和现在我们所熟知的缓存模式、池化模式有所联系,却又有不同。看完这篇文章后,相信你会找到这个不同之处。
一、模式原理分析
享元模式的原始定义是:摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,从而让我们能在有限的内存容量中载入更多对象。
从这个定义中你可以发现,享元模式要解决的核心问题就是节约内存空间,使用的办法是找出相似对象之间的共有特征,然后复用这些特征。
我们先来看看 UML 图是如何表示享元模式的,如下图:
从这个 UML 图中,我们能看出享元模式包含的关键角色有四个。
-
享元类(Flyweight):定义了享元对象需要实现的公共操作方法。在该方法中会使用一个状态作为输入参数,也叫外部状态,由客户端保存,在运行时改变。
-
享元工厂类(Flyweight Factory):管理一个享元对象类的缓存池。它会存储享元对象之间需要传递的共有状态,比如,按照大写英文字母来作为状态标识,这种只在享元对象之间传递的方式就叫内部状态。同时,它还提供了一个通用方法 getFlyweight(),主要通过内部状态标识来获取享元对象。
-
可共享的具体享元类(ConcreteFlyweight):能够复用享元工厂内部状态并实现享元类公共操作的具体实现类。
-
非共享的具体享元类(UnsharedConcreteFlyweight):不复用享元工厂内部状态,但实现享元类的具体实现类。
下面我们再来看看 UML 对应的代码实现:
//享元类
public interface Flyweight {
void operation(int state);
}
//享元工厂类
public class FlyweighFactory {
// 定义一个池容器
public Map<String,Flyweight> pool = new HashMap<>();
public FlyweighFactory() {
pool.put("A"