(C++设计模式) ------享元模式-- 结构型模式
设计模式的学习是一个循序渐进的过程,每一个设计师都是在套用这几种设计模式来实现自己的软件构架,很多都是融合会贯通的,一个设计模式中不仅仅是用到一种,所以要灵活运用这些设计模式。理解了设计模式对设计和代码的阅读都有很大的好处!!
今天我们学习结构性模式享元(flyweight)模式;
Flyweight—每天跟MM发短信,手指都累死了,最近买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了,再不用一个字一个字敲了。共享的句子就是Flyweight,MM的名字就是提取出来的外部特征,根据上下文情况使用。
享元模式:FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。说的再具体一些是将所有具有相同状态的对象指向同一个引用,从而解决了系统在创建大量对象时所带来的内存压力。
享元模式能做到共享的关键是区分内蕴状态和外蕴状态。
内蕴状态存储在享元内部并且可以共享,不会随环境的改变而有所不同。
外蕴状态是随环境的改变而改变的,不可以共享。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。
亨元对象的外蕴状态必须由客户端保存,并在亨元对象被创建之后,在需要使用的时候再传入到亨元对象内部。
注意:客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
使用的场合:
- 需要创建大量对象。
- 考虑内存成本。
- 大多数对象属性可以对外共享。
- 应用程序不必授权给唯一的对象,因为同一对象被实例后需要被重复使用。
例子:
比如围棋有300颗棋子,用一般的设计模式,创建一个类,每个棋子都用一个对象的话那就会非常麻烦,并且各自定义各自在棋盘的位置.....等等而使用亨元模式来实现的话,就用两个对象 :一个黑,一个白。这样就可以了,至于棋子的方位不同,那只是对象的不同的外部表现形式或者说是外部状态。这样三百多个对象就减到了两个对象。优缺点:优点:减少对象数量,节省内存空间
缺点:维护共享对象,需要额外开销换句话说就是:享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。另外它将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
本质:
分离与共享
-
代码举例:引用自:http://blog.csdn.net/roynee/article/details/4633474
-
以纯文本为例,每个字符CharFlyweight为共享的轻量级对象,而由这些字符构成的行则为非共享的对象RowFlyweight,而TextFlyweightFactory则管理其共享对象的对象池。当用户向该工厂请求字符时,就从对象池中取得,而当用户向该工厂请求字符串时候则通过创建非共享的RowFlyweight获取,但此种每个字符的获取仍然向TextFlyweightFactory共享对象的对象池提出请求。
-
【程序】
-
运行结果:
-
{
RowFlyweight *row=new RowFlyweight();
for(int i=0;i < str.length() -1;++i) //这地方改成减一
row->AddFlyweight(this->GetFlyweight(str[i])); /*Get the char from VecCharFlyweight*/
return row;
} - 然后main函数修改一下更能体现共享的概念:
- 输出结果是: