抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
C++的抽象工厂模式有如下优势:
1)正如起名字,抽象工厂模式隔离具体类的生产,使客户不需要知道什么被创建。
2)当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
3)增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
而缺点是:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。
下面直接给一个C++实例来说明抽象工厂模式的实现
#include <string>
#include <map>
#include <list>
#include <stdio.h>
#define USERS_PARAM(X) X;
class ZBSBase
{
public:
ZBSBase(){}
virtual bool InitParam(const std::string& strParam) = 0;
virtual void Excute() = 0;
virtual void End() = 0;
};
class ZBSMessage : public ZBSBase
{
public:
ZBSMessage():m_bInit(false){}
virtual bool InitParam(const std::string& strParam)
{
m_bInit = true;
USERS_PARAM(strParam);
return true;
}
virtual void Disp()
{
printf("ZBSMessage::Disp!\n");
}
virtual void End()
{
printf("ZBSMessage::End!\n");
}
virtual void Excute()
{
if (!m_bInit) return;
printf("ZBSMessage::Excute!\n");
Disp();
End();
}
protected:
bool m_bInit;
};
class ZBSEncodeMessage : public ZBSMessage
{
public:
ZBSEncodeMessage(){}
virtual void Disp()
{
printf("ZBSEncodeMessage::Disp\n");
}
};
class ZBSJsonMessage : public ZBSMessage
{
public:
ZBSJsonMessage(){}
virtual void Disp()
{
printf("ZBSJsonMessage::Disp\n");
}
};
class ZBSXMLMessage : public ZBSMessage
{
public:
ZBSXMLMessage(){}
virtual void Disp()
{
printf("ZBSXMLMessage::Disp\n");
}
};
class ZBSCreatorBase
{
public:
ZBSCreatorBase(){}
virtual ZBSMessage* Create() = 0;
};
template<class T>
class ZBSCreator :public ZBSCreatorBase
{
public:
ZBSCreator(const std::string& strkey = "") :m_strKey(strkey){}
ZBSMessage* Create()
{
return new T;
}
private:
std::string m_strKey;
};
class ZBSFactoryMgr
{
ZBSFactoryMgr(){}
public:
static ZBSFactoryMgr& Instance()
{
static ZBSFactoryMgr s_Instance;
return s_Instance;
}
void AddZBSCreator(const std::string& strClassName, ZBSCreatorBase* pZBSCreator)
{
if (m_mapZBSCreator.find(strClassName) == m_mapZBSCreator.end())
{
m_mapZBSCreator.insert(make_pair(strClassName, pZBSCreator));
}
}
ZBSMessage* CreatorZBSInstace(const std::string& strKey)
{
ZBSMessage* pZBSObj = NULL;
std::map<std::string, ZBSCreatorBase*>::iterator it;
it = m_mapZBSCreator.find(strKey);
if (it != m_mapZBSCreator.end())
{
pZBSObj = it->second->Create();
}
return pZBSObj;
}
int GetMapSize()
{
return m_mapZBSCreator.size();
}
private:
std::map<std::string, ZBSCreatorBase*> m_mapZBSCreator;
};
#define REGISTER_ZBSFACTORY(ClassName)\
ZBSFactoryMgr::Instance().AddZBSCreator(#ClassName, new ZBSCreator<ClassName>());
extern "C" ZBSMessage* CreateZBSMessage(const std::string& strKey)
{
return ZBSFactoryMgr::Instance().CreatorZBSInstace(strKey);
}
int main()
{
REGISTER_ZBSFACTORY(ZBSXMLMessage);
REGISTER_ZBSFACTORY(ZBSJsonMessage);
REGISTER_ZBSFACTORY(ZBSEncodeMessage);
ZBSMessage *pm1;
ZBSMessage *pm2;
ZBSMessage *pm3;
std::list<ZBSMessage*> ls;
std::list<ZBSMessage*>::iterator it;
pm1 = CreateZBSMessage("ZBSXMLMessage");
pm2 = CreateZBSMessage("ZBSJsonMessage");
pm3 = CreateZBSMessage("ZBSEncodeMessage");
ls.push_back(pm1);
ls.push_back(pm2);
ls.push_back(pm3);
int nSize = ls.size();
it = ls.begin();
for (it; it != ls.end(); it++)
{
(*it)->InitParam("");
(*it)->Excute();
}
return 0;
}
输出结果如下:
ZBSMessage::Excute!
ZBSXMLMessage::Disp
ZBSMessage::End!
ZBSMessage::Excute!
ZBSJsonMessage::Disp
ZBSMessage::End!
ZBSMessage::Excute!
ZBSEncodeMessage::Disp
ZBSMessage::End!
首先看下,首先声明了基类ZBSBase,之后继承ZBSBase类得到ZBSMessage类,下面定义了是那个用户用到的类,即需要“工厂生产”的类,分别用于处理Encode、Json和XML文件消息的类ZBSEncodeMessage、ZBSJsonMessage和ZBSXMLMessage。
接下来声明ZBSCreator类用来创建ZBSMessage类,ZBSFactoryMgr用来实现抽象工厂,我们来看抽象工厂的具体实现代码,首先看main函数的前3行代码:
REGISTER_ZBSFACTORY(ZBSXMLMessage);
REGISTER_ZBSFACTORY(ZBSJsonMessage);
REGISTER_ZBSFACTORY(ZBSEncodeMessage);
以REGISTER_ZBSFACTORY(ZBSXMLMessage)为例,其实际执行的代码为(注意C++中,符号#将传入的参数变为字符串,字符串化,而符号##为合并操作符,将出现在其左右的字符序列合并成一个新的标志符,注意是标志符不是字符串):
s_Instance.AddZBSCreator(“ZBSXMLMessage”, new ZBSCreator<ZBSXMLMessage>());
即m_mapZBSCreator中插入了3个对应消息类类型的ZBSCreator类实例,这里并创建消息类实例,接着执行:
pm1 = CreateZBSMessage("ZBSXMLMessage");
pm2 = CreateZBSMessage("ZBSJsonMessage");
pm3 = CreateZBSMessage("ZBSEncodeMessage");
此时会新建消息类的实例并返回指针,也就是通过宏定义REGISTER_ZBSFACTORY和CreateZBSMessage就可以一抽象工厂的方式创建一个具体消息类实例并返回了指针。