设计模式-结构型-享元模式(Flyweight)
参考文献
享元模式
- 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象.
- 此模式的目的是使用共享来支持大量对象,这些对象的内部状态的一部分是相同的,而状态的其他部分可能会有所不同.
组件
Flyweight
: 声明一个接口,通过该接口,flyweight
可以接收外部状态并对其进行操作ConcreteFlyweight
: 实现Flyweight
接口并存储内在状态.ConcreteFlyweight
对象必须是可共享的.具体的享元对象必须维持其固有的状态,并且必须能够操纵外在的状态FlyweightFactory
: 工厂创建和管理 Flyweight 对象.此外,工厂还确保享元对象的共享.工厂维护一个不同的享元对象池,如果已经创建了对象,则从池中返回一个对象;如果是新对象,则向池中添加一个对象并返回该对象Client
: 除了计算和维护外部状态之外,客户端还维护对享元的引用- 客户端需要一个享元对象;它调用工厂来获取享元对象.工厂检查享元池以确定所请求类型的享元对象是否在池中,如果存在,则返回对该对象的引用.如果没有所需类型的对象,工厂将创建所需类型的享元,将其添加到池中,并返回对该享元的引用.享元维护内部状态(在我们为其创建享元的大量对象之间共享的状态)并提供操作外部状态的方法(状态因对象而异,并且在我们为其创建的对象中并不常见)
实现方式
-
确定内在状态(
Intrinsic State
)和外在状态(Extrinsic State
)- 内在状态指对象可以共享的不变数据,可以被多个对象共享.
- 外在状态指对象的上下文相关数据,每个对象都可能不同.
-
创建享元接口(
Flyweight
),定义对象的共享方法1
2
3public interface Flyweight {
void operation(ExtrinsicState state);
} -
创建具体享元类,实现享元接口,并存储内在状态(
Intrinsic State
):1
2
3
4
5
6
7
8
9
10
11
12
13public class ConcreteFlyweight implements Flyweight {
private IntrinsicState intrinsicState;
public ConcreteFlyweight(IntrinsicState intrinsicState) {
this.intrinsicState = intrinsicState;
}
public void operation(ExtrinsicState state) {
// 使用内在状态和外在状态执行操作
// ...
}
} -
创建享元工厂类,用于管理和提供享元对象:
1
2
3
4
5
6
7
8
9
10
11public class FlyweightFactory {
private Map<String, Flyweight> flyweights = new HashMap<>();
public Flyweight getFlyweight(String key) {
if (!flyweights.containsKey(key)) {
// 创建新的享元对象并添加到缓存中
flyweights.put(key, new ConcreteFlyweight(intrinsicState));
}
return flyweights.get(key);
}
} -
定义外在状态(
Extrinsic State
)类,用于存储对象的上下文相关数据:1
2
3
4public class ExtrinsicState {
// 存储外在状态的数据
// ...
} -
在客户端中使用享元模式:
1
2
3
4
5
6
7
8FlyweightFactory factory = new FlyweightFactory();
Flyweight flyweight = factory.getFlyweight("key");
ExtrinsicState state1 = new ExtrinsicState(...);
flyweight.operation(state1);
ExtrinsicState state2 = new ExtrinsicState(...);
flyweight.operation(state2);
使用场景
- 仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式
- 应用该模式所获的收益大小取决于使用它的方式和情景. 它在下列情况中最有效:
- 程序需要生成数量巨大的相似对象
- 这将耗尽目标设备的所有内存
- 对象中包含可抽取且能在多个对象间共享的重复状态.
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HoleLin's Blog!