设计模式十二:flyweight(享元模式)——对象结构型模式
flyweight(享元模式)——对象结构型模式
1.意图
运用共享技术有效地支持大量细粒度对象
2.动机
flyweight作为一个共享对象,可以同时在多个场景中使用,并且在每个场景中flyweight都可以作为一个独立的对象。
flyweight不能为他所运行的场景做出任何假设,这里的关键概念是内部状态和外部状态之间的区别。
内部状态存储于flyweight中,包含了flyweight场景的信息,这些信息使得flyweight可以被共享。
外部状态取决于flyweight场景,并且根据场景而变化,因此不可以被共享。用户对象负责在必要的时候将外部状态传递给flyweight。
flyweight通常可以对那些因为数量太大而难以用对象来表示的改变或者实体进行建模。
3.适用性
flyweight的有效性很大程度上取决于如何使用他以及在何处使用他。以下情况都成立时使用flyweight模式
一个应用程序使用了大量的对象
完全由于使用大量的对象,造成很大的内存开销
对象的大多数状态都可变为外部状态
如果删除对象的外部装态,那么可以用相对较少的共享对象取代很多组对象
应用程序不依赖于对象标识
4.结构

参考:http://www.cnblogs.com/sunjinpeng/archive/2012/04/06/2433603.html
5.参与者
flyweight
描述一个接口,通过这个接口flyweight可以接受并作用于外部状态
concreteflyweight
实现flyweight接口,并为内部状态增加存储空间,concreteflyweight必须是可以被共享的,他所存储的状态必须是内部的,即必须独立于concreteflyweight对象的场景。
unsharedConcreteFlyweight
并非所有的flyweight子类都需要被共享。flyweight的接口为共享提供可能,但是他并不是强制共享。
flyweightFactory
创建并管理flyweight对象
确保合理地共享flyweight。当用户请求一个flyweight时,flyweightFactory对象提供一个已经创建的实例或者新创建一个。
client
维持一个对flyweight的引用
计算或者存储一个(多个)flyweight的外部状态。
6.协作
flyweight执行时所需的状态必定是内部的或者是外部的,内部状态存储于concreteflyweight对象之中,而外部对象则由client对象存储,当用户调用flyweight对象的操作时,将该状态传递给他。
用户不应该直接对concreteflyweight类进行实例化,二十只能从flyweightFactory对象得到concreteflyweight对象,这保证对他们适当的进行共享。
7.效果
会增加一些传输、查找、和计算的开销,但是空间上的节省抵消了这些开销。共享的flyweight越多,节省也越多。
当对象使用大量的内部及外部状态,且外部状态是计算出来的而非存储的时候,节约量将达到最大。
8.实现
1)删除外部状态
该模式的可用性在很大程度上取决于是否容易识别外部状态并将它从共享对象中删除。如果不同种类的外部状态和共享前对象的数目相同的话,删除外部状态不会降低存储消耗。理想状态是,外部状态可以由一个单独的对象结构计算得到,且该结构的存储要求非常小。
2)管理共享对象
对象是共享的,所以用户不能直接对其进行实例化,所以用flyweightfactory来进行管理。
9.代码示例
#include<iostream> #include<map> #include<string> using namespace std; class menue { public: virtual void dosth(int num){}; }; class dish:public menue { public: dish(string name) { dishName = name; } void dosth(int num) { cout<<"get "<<num<<" of "<<dishName<<endl; } private: string dishName; }; class dishFactory { private: map<string, menue*> m; public: menue* factory(string str) { if(!m[str]) { cout<<"generate a new dish"<<endl; m[str] = new dish(str); } else cout<<"output a existing dish"<<endl; return m[str]; } }; int main() { dishFactory *df = new dishFactory(); menue *v = df->factory("vegetable"); v->dosth(3); v->dosth(4); menue *m = df->factory("meat"); m->dosth(1); m->dosth(2); menue *ve = df->factory("vegetable"); ve->dosth(5); }
10.相关模式
flyweight通常和composite模式结合起来,用共享叶节点的有向无环图实现一个逻辑上的层次结构。
最好用flyweight实现state和strategy对象
浙公网安备 33010602011771号