享元模式,用于降低对象的粒度,即减少对象的个数。需要对类做很好的抽象,共享其内部特征,通过不同的外部特征传入来创建最少的对象。也就是说,有时需要生成大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数外基本上都是相同的,有时就能够最大幅度的减少需要实例化的类的数量,如果能把那些参数转移到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度的减少单个实例的数目。内部状态存储于对象之中,外部对象则考虑由客户端对象存储或计算。( 摘抄于《大话设计模式》)
关键点:
1.需要有一个工厂来管理对象的生成,而不是由类直接来生成对象。
2.工厂类的内部需要判断要创建的对象是否已经存在,存在则共享,反之则创建。
3.抽象享元类,分清内部特征,与外部特征。并使之分离。
下面则是该模式的一个例子。围棋:颜色为其内部特征(其实颜色还可抽离为外部特征),坐标为其外部特征。
#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
using namespace std;
//围棋棋子的坐标,其棋子享元的外部属性,也可以用类来抽象实现
struct CORDINARY
{
int x;
int y;
};
//围棋棋子的享元,其内部属性为颜色
class CFlyWeight
{
public:
CFlyWeight(){ m_szColor = "";};
CFlyWeight(string szColor):m_szColor(szColor){};
virtual ~CFlyWeight(){};
virtual void Operation( CORDINARY cord) = 0;
string GetColor(){ return m_szColor; };
protected:
string m_szColor;
};
//享元的实现类
class CChess:public CFlyWeight
{
public:
CChess(string szColor):CFlyWeight(szColor){};
CChess(){};
virtual ~CChess(){};
virtual void Operation(CORDINARY cord);
};
void CChess::Operation(CORDINARY cord)
{
cout<<"color is :"<<m_szColor<<
"location is: "<<cord.x<<" "<<cord.y<<endl;
}
//享元的工厂类,用于管理对象,和共享对象
class CFlyWeightFactory
{
public:
CFlyWeightFactory(){};
~CFlyWeightFactory();
CFlyWeight* CreateChess( string szColor);
size_t GetObjCount(){ return m_objDictonary.size(); };
private:
map<string, CFlyWeight*> m_objDictonary; //对象字典,用来管理对象
};
//享元工厂的析构函数
CFlyWeightFactory::~CFlyWeightFactory()
{
for ( map<string, CFlyWeight*>::iterator i = m_objDictonary.begin();
i != m_objDictonary.end();i++)
{
delete (*i).second;
}
}
//共享对象的实现
CFlyWeight* CFlyWeightFactory::CreateChess( string szColor)
{
map<string, CFlyWeight*>::iterator pObj = NULL;
pObj = m_objDictonary.find(szColor);
//对象管理,如已有要创建的对象,则共享该对象,反之则创建该对象
if ( pObj == m_objDictonary.end())
{
m_objDictonary.insert(make_pair(szColor, new CChess(szColor)));
pObj = m_objDictonary.find(szColor);
}
return (*pObj).second;
}
int main()
{
CORDINARY cord[] = { {10,20} ,
{20,30}};
//创建享元工厂
CFlyWeightFactory* cfwf = new CFlyWeightFactory;
//创建白色棋子。并打印有几个对象
CFlyWeight* chess = cfwf->CreateChess("white");
chess->Operation(cord[0]);
chess->Operation(cord[1]);
cout<<"the count of the object is "<<cfwf->GetObjCount()<<endl;
//创建黑色棋子,并打印有几个对象
chess = cfwf->CreateChess("black");
chess->Operation(cord[0]);
chess->Operation(cord[1]);
cout<<"the count of the object is "<<cfwf->GetObjCount()<<endl;
//释放工厂对象
delete cfwf;
int a = 0;
cin>>a;
return 0;
}