首页 > 代码库 > 享元模式之C++实现
享元模式之C++实现
说明:本文仅供学习交流,转载请标明出处,欢迎转载!
享元模式(Flyweight)主要体现在“享”上,即共享。设想这么一种情况,现在有编号为A、B三栋房子,现在外面有9只大熊过来了,编号为1~9。现在规定,编号为1~3的熊只能居住在编号为A的房子中,编号为4~6的大熊只能居住在编号为B的大熊中,编号为7~9的大熊只能居住在编号为C的房子中。假如大熊非常笨,没有受过教育,它们只知道自己住的房子的编号。之所以大熊笨,是因为它们一来就建房子,然后在所建的房子墙上写上自己对应的住房编号。这样到最后的结果必然是:建造了9栋房子,3栋编号为A的房子、3栋编号为B的房子、3栋编号为C的房子。
为了防止上述现象的发生,我们可以这么做:每只大熊在建房之前看下自己所对应编号的住房是否存在,如果存在就直接住在里面,如果不存在,就开始建房。这样一来,最终的结果便是:编号为1~3的大熊一起住在原有的A栋房子里面,编号为4~6的大熊一起住在原有的B栋房子里面,编号为7~9的大熊一起住在新建的C栋房子里。这样,最后的结果必然是:总共有3栋房子,编号为A、B和C的房子各仅有一栋。
显然,两种结果对比:后者的结果要比前者好得多,因为效率要高于前者,而且也不会浪费那么大的空间。我们可以称后者采用的就是“享元模式”。
享元模式的定义:运用共享技术有效地支持大量细粒度的对象。
享元模式结构
本图来自《大话设计模式》
C++代码实现
#include<iostream> #include<map> #include<string> using namespace std; class Flyweight//抽象的享元类 { public: virtual void Operation(int i)=0; }; class ConcreteFlyWeight:public Flyweight//共享的子类 { public: void Operation(int i) { cout<<"共享的FlyWeight:"<<i<<endl; } }; class UnsharedConcreteFlyweight:public Flyweight//不共享的子类 { void Operation(int i) { cout<<"不共享的FlyWeight:"<<i<<endl; } }; class FlyweightFactory//享元工厂 { private: map<string,Flyweight*>flyweights;//模块名列表 public: FlyweightFactory()//初始共享模块列表 { flyweights["X"]=new ConcreteFlyWeight();//这里需要用堆,因为这是给客户程序返回的,如果不用堆,则会返回局部对象的引用 flyweights["Y"]=new ConcreteFlyWeight(); flyweights["Z"]=new ConcreteFlyWeight();//所有的属性为“Z”的模块都只对应这个一个实例,这正是享元模式的精髓所在呀 } Flyweight* GetFlyWeight(string key)//工厂返回享元对象,而这些对象的属性都存放在一个该工厂的模块名列表中 { if(!flyweights.count(key) )//先检查下是否在列表中,如果不在则新建该列表项 { flyweights[key]=new ConcreteFlyWeight();//这里只能返回堆空间,否则在主函数中将出处 } return flyweights[key]; } map<string,Flyweight*>::size_type countN()//返回当前有多少个可供共享的模块 { return flyweights.size(); } }; int main() { int i=100; FlyweightFactory f;//整个过程值采用一个工厂 Flyweight *px=f.GetFlyWeight("X");//获取X对应的模块,相当于用属性列表给固定部分穿上衣服 px->Operation(--i); Flyweight *py=f.GetFlyWeight("Y");//获取Y对应的模块 py->Operation(--i); Flyweight *pd=f.GetFlyWeight("D");//D不在初始化列表中,但会自动加入到列表中 pd->Operation(--i); cout<<"可供共享的模块有:"<<f.countN()<<"个!"<<endl; /*******C++的哪些繁琐事儿!!!防止内存泄露*********/ delete px; delete py; delete pd; return 0; }
测试结果
参考资料:
[1]《大话设计模式》
[2]《设计模式之禅》
[3]《HeadFirst设计模式》