首页 > 代码库 > 享元模式之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设计模式》