享元模式
Flyweight
目录
定义
所谓享元模式就是运行共享技术有效地支持大量细粒度对象的复用。系统使用少量对象,而且这些都比较相似,状态变化小,可以实现对象的多次复用。
共享模式是支持大量细粒度对象的复用,所以享元模式要求能够共享的对象必须是细粒度对象。
- 内部状态:在享元对象内部不随外界环境改变而改变的共享部分。
- 外部状态:随着环境的改变而改变,不能够共享的状态就是外部状态。
由于享元模式区分了内部状态和外部状态,所以我们可以通过设置不同的外部状态使得相同的对象可以具备一些不同的特性,而内部状态设置为相同部分。在我们的程序设计过程中,我们可能会需要大量的细粒度对象来表示对象,如果这些对象除了几个参数不同外其他部分都相同,这个时候我们就可以利用享元模式来大大减少应用程序当中的对象。如何利用享元模式呢?这里我们只需要将他们少部分的不同的部分当做参数移动到类实例的外部去,然后再方法调用的时候将他们传递过来就可以了。这里也就说明了一点:内部状态存储于享元对象内部,而外部状态则应该由客户端来考虑。
结构
参与者:
- Flyweight: 抽象享元类。所有具体享元类的超类或者接口,通过这个接口,Flyweight可以接受并作用于外部专题。
- ConcreteFlyweight: 具体享元类。指定内部状态,为内部状态增加存储空间。
- UnsharedConcreteFlyweight: 非共享具体享元类。指出那些不需要共享的Flyweight子类。
- FlyweightFactory: 享元工厂类。用来创建并管理Flyweight对象,它主要用来确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory就会提供一个已经创建的Flyweight对象或者新建一个(如果不存在)。
享元模式的核心在于享元工厂类,享元工厂类的作用在于提供一个用于存储享元对象的享元池,用户需要对象时,首先从享元池中获取,如果享元池中不存在,则创建一个新的享元对象返回给用户,并在享元池中保存该新增对象。
|
|
实现
场景:假如我们有一个绘图的应用程序,通过它我们可以出绘制各种各样的形状、颜色的图形,那么这里形状和颜色就是内部状态了,通过享元模式我们就可以实现该属性的共享了。
抽象享元类
|
|
具体享元类,绘制圆形的具体类
|
|
享元工厂类
|
|
客户端
|
|
优缺点
优点
- 享元模式的优点在于它能够极大的减少系统中对象的个数。
- 享元模式由于使用了外部状态,外部状态相对独立,不会影响到内部状态,所以享元模式使得享元对象能够在不同的环境被共享。
缺点
- 由于享元模式需要区分外部状态和内部状态,使得应用程序在某种程度上来说更加复杂化了。
- 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变长。
适用场景
- 如果一个系统中存在大量的相同或者相似的对象,由于这类对象的大量使用,会造成系统内存的耗费,可以使用享元模式来减少系统中对象的数量。
- 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
总结
- 享元模式可以极大地减少系统中对象的数量。但是它可能会引起系统的逻辑更加复杂化。
- 享元模式的核心在于享元工厂,它主要用来确保合理地共享享元对象。
- 内部状态为不变共享部分,存储于享元享元对象内部,而外部状态是可变部分,它应当油客户端来负责。