目录
前言
当我们需要使用大量细粒度对象时,如果每个都需要创建实例,可能会浪费大量空间。如果这些对象有共同的内部状态,我们可以考虑使用Flyweight模式。
1 定义
Flyweight:运用共享技术支持大量细粒度的对象。
2 适用性
- 程序使用了大量的对象。
- 使用大量对象造成了存储开销。
- 对象的大多数状态都可以变为外部状态。
- 如果不考虑对象的外部状态,可以使用共享对象代替大量重复的实例对象。
- 应用程序不依赖对象表示,否则对象不应该被共享。
3 结构
3.1 结构图
基本结构图
下面说明了如何共享flyweight
可见创建的共享flyweight,可以有多个客户获取其指针,进而获取其不变的内部状态,进行外部操作。
3.2 参与者
- Flyweight:接口,通过这个接口封装内部状态,可以接受外部状态。
- ShareFlyweight:具体flyweight,可共享的,应该独立于其外部场景。
- UnShareFlyweight:非共享的flyweight,正常可以多次实例化。
- Client:维持flyweight指针;对一个flyweight做一个或多个外部状态计算。
4 Java举例
Integer、Long等类型均使用了内部缓存作为对象共享使用。下面以Integer为例
4.1 Flyweight——Integer
Integer封装基本类型int,增加各种操作。定义如下:
public final class Integer extends Number implements Comparable<Integer> {
/**
* A constant holding the minimum value an {@code int} can
* have, -2<sup>31</sup>.
*/
@Native public static final int MIN_VALUE = 0x80000000;
/**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1.
*/
@Native public static final int MAX_VALUE = 0x7fffffff;
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
主要使用value存储int值。
4.2 FlyweightFactory——Integer
本身可以看作一个工厂,内部_pool就是Integer内部静态类IntegerCache:
通过cache缓存共享对象(范围是-128-127)。如果我们通过需要使用Integer共享对象,只需要调用valueOf(int i)方法即可,该方法是通过缓存cache获取已经存在的对象。
5 总结
当系统存在大量对象,而这里对象存在一些内部状态不经常随着场景变化,则可以考虑拆分对象内部状态和外部状态,从而可以使用flyweight模式创建共享对象,节约存储空间。
参考文献
[1]. 《设计模式》