[设计模式笔记]二. 结构型模式--12.Flyweight模式(享元模式)(一)

结构型模式--Flyweight模式(享元)


一. 意图


运用共享技术有效地支持大量细粒度的对象.


二. 适用性


Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用它

当以下情况都成立时使用Flyweight模式:

1. 一个应用程序使用了大量的对象。

2. 完全由于使用大量的对象,造成很大的存储开销。

3. 对象的大多数状态都可变为外部状态。

4. 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

5. 应用程序不依赖于对象标识.


三. 模式结构

[设计模式笔记]二. 结构型模式--12.Flyweight模式(享元模式)(一)_第1张图片

图1 


四. 角色说明


Flyweight

—描述一个接口通过这个接口flyweight可以接受并作用于外部状态.

ConcreteFlyweight

—实现Flyweight接口并为内部状态提供存储空间ConcreteFlyweight对象必须是可共享的它所存储的状态必须是内部的:即它必须独立于ConcreteFlyweight对象的场景(独立于上下文), 客户在调用其操作时需要把外部状态传递给它使用(但不会保存).

UnsharedConcreteFlyweight

—并非所有的Flyweight子类都需要被共享. Flyweight接口使共享成为可能但它并不强制共享Flyweight对象结构的某些层次, UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点.

FlyweightFactory

—创建并管理Flyweight对象。

—确保合理地共享Flyweight. 当用户请求一个Flyweight, FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在的话)(创建ConcreteFlyweight)

Client 

—维持一个对Flyweight的引用。

—计算或存储一个(多个)Flyweight的外部状态。

Flyweight执行时所需的状态必定是内部的或外部的内部状态存储于ConcreteFlyweight对象之中而外部对象则由Client对象存储或计算当用户调用Flyweight对象的操作时将该状态传递给它用户不应直接对ConcreteFlyweight类进行实例化,而只能从FlyweightFactory对象得到ConcreteFlyweight对象这可以保证对它们适当地进行共享.


五. 代码


// 创建ConcreteFlyweight对象(存储内部状态的对象)
FlyweightFactory::GetFlyweight(key)
{
	if(flyweight[key] exists)			// 这里的创建策略可以根据需求而定.
		return existing flyweight		// 你可以一开始就直接创建.
	else								// 但如果为了省空间, 那就需要时才创建也可以.
		new ConcreteFlyweight
		add it to pool of flyweights
		return it               
}

// 客户
// 获得key对应的享元对象.
ConcreteFlyweight* pConcreteFlyweight = FlyweightFactory::GetFlyweight(key);

// 计算外部状态
extrinsicState = ..... // 外部状态由客户管理, 计算也好, 存储也好.

// 调用享元对象的某些操作
pConcreteFlyweight->Operation(extrinsicState);
// pConcreteFlyweight对象的内部状态自己存储, 所以不需要传递.
// 这里没有用到UnsharedConcreteFlyweight(暂时不是很明白), 


六. 说明


Flyweight模式经常和Composite模式结合起来表示一个层次式结构这一层次式结构是一个共享叶节点的图共享的结果是, Flyweight的叶节点不能存储指向父节点的指针而父节点的指针将传给Flyweight作为它的外部状态的一部分这对于该层次结构中对象之间相互通讯的方式将产生很大的影响(不是很明白!).

共享的Flyweight越多存储节约也就越多节约量随着共享状态的增多而增大当对象使用大量的内部及外部状态并且外部状态是计算出来的而非存储的时候节约量将达到最大所以可以用两种方法来节约存储用共享减少内部状态的消耗用计算时间换取对外部状态的存储.


我的理解


1. 你必须正确分离出内部状态与外部状态.

2. 外部状态由客户管理.

3. 内部状态需要存储下来共享.

4. 如果外部状态不是通过计算出来的内存就省不下来了.(用时间换空间).

5. 假设有10个内部状态, 1000个外部状态如果他们不分离开那就代表需要  1000 个单位的存储空间因为即使那1000个外部状态可以通过计算得到但是由于内外部没有分离没共享那么还是需要1000个对象来存储内部状态.

6. Flyweight模式把内部状态和外部状态分离假设1000个外部状态中100个是不能动态计算出来的(它们又不能作为内部状态), 100 个单位空间是省不了的.

7. FlyweightFactory需要管理好Flyweight对象.


相关模式


Flyweight模式通常和Composite模式结合起来用共享叶结点的有向无环图实现一个逻辑上的层次结构通常最好用Flyweight实现StateStrategy对象.

你可能感兴趣的:(设计模式,享元模式,Flyweight模式,结构型模式)