设计模式: 抽象工厂模式(Abstract Factory)
问题
假设我们要开发一款游戏,当然为了吸引更多的人玩,游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理)。于是我们就可以采用这样一种处理策略:为游戏设立等级,初级、中级、高级甚至有BT 级。假设也是过关的游戏,每个关卡都有一些怪物(monster)守着,玩家要把这些怪物干掉才可以过关。作为开发者,我们就不得不创建怪物的类,然后初级怪物、中级怪物等都继承自怪物类(当然不同种类的则需要另创建类,但是模式相同)。在每个关卡,我们都要创建怪物的实例,例如初级就创建初级怪物(有很多种类)、中级创建中级怪物等。可以想象在这个系统中,将会有成千上万的怪物实例要创建,问题是还要保证创建的时候不会出错:初级不能创建 BT 级的怪物(玩家就郁闷了,玩家一郁闷,游戏也就挂挂了),反之也不可以。
AbstractFactory模式就是用来解决这类问题的:要创建一组相关或者相互依赖的对象。
模式选择
Abstract Factory模式典型的结构图为:
![](http://images0.cnblogs.com/blog/168241/201304/01140030-000220642793438f8b121a05f7736005.png)
Abstract Factory 模式关键就是将这一组对象的创建封装到一个用于创建对象的类(ConcreteFactory)中,维护这样一个创建类总比维护 n 多相关对象的创建过程要简单的多。
实现
// IPhone.h #ifndef __IPHONE_H__ #define __IPHONE_H__ class IPhone { public: IPhone(){}; virtual ~IPhone(){}; virtual void showName() = 0; }; #endif // Phone.h #ifndef __PHONE_H__ #define __PHONE_H__ #include "IPhone.h" class CMX1Phone:public IPhone { public: CMX1Phone(); virtual ~CMX1Phone(); virtual void showName(); }; class CMX2Phone:public IPhone { public: CMX2Phone(); virtual ~CMX2Phone(); virtual void showName(); }; class CMX3Phone:public IPhone { public: CMX3Phone(); virtual ~CMX3Phone(); virtual void showName(); }; class CMI1Phone:public IPhone { public: CMI1Phone(); virtual ~CMI1Phone(); virtual void showName(); }; class CMI2Phone:public IPhone { public: CMI2Phone(); virtual ~CMI2Phone(); virtual void showName(); }; #endif // Phone.cpp #include "Phone.h" #include <iostream> CMX1Phone::CMX1Phone() { } CMX1Phone::~CMX1Phone() { } void CMX1Phone::showName() { std::cout << "I am mx1 of meizu!\n"; } CMX2Phone::CMX2Phone() { } CMX2Phone::~CMX2Phone() { } void CMX2Phone::showName() { std::cout << "I am mx2 of meizu!\n"; } CMX3Phone::CMX3Phone() { } CMX3Phone::~CMX3Phone() { } void CMX3Phone::showName() { std::cout << "I am mx3 of meizu!\n"; } CMI1Phone::CMI1Phone() { } CMI1Phone::~CMI1Phone() { } void CMI1Phone::showName() { std::cout << "I am mi1 of xiaomi!\n"; } CMI2Phone::CMI2Phone() { } CMI2Phone::~CMI2Phone() { } void CMI2Phone::showName() { std::cout << "I am mi2 of xiaomi!\n"; } // IBattery.h #ifndef __IBATTERY_H__ #define __IBATTERY_H__ class IBattery { public: IBattery(){}; virtual ~IBattery(){}; virtual void showName() = 0; }; #endif // Battery.h #ifndef __BATTERY_H__ #define __BATTERY_H__ #include "IBattery.h" class CMX1Battery:public IBattery { public: CMX1Battery(); virtual ~CMX1Battery(); virtual void showName(); }; class CMX2Battery:public IBattery { public: CMX2Battery(); virtual ~CMX2Battery(); virtual void showName(); }; class CMX3Battery:public IBattery { public: CMX3Battery(); virtual ~CMX3Battery(); virtual void showName(); }; class CMI1Battery:public IBattery { public: CMI1Battery(); virtual ~CMI1Battery(); virtual void showName(); }; class CMI2Battery:public IBattery { public: CMI2Battery(); virtual ~CMI2Battery(); virtual void showName(); }; #endif // Battery.cpp #include "Battery.h" #include <iostream> CMX1Battery::CMX1Battery() { } CMX1Battery::~CMX1Battery() { } void CMX1Battery::showName() { std::cout << "I am mx1's battery of meizu!\n"; } CMX2Battery::CMX2Battery() { } CMX2Battery::~CMX2Battery() { } void CMX2Battery::showName() { std::cout << "I am mx2's battery of meizu!\n"; } CMX3Battery::CMX3Battery() { } CMX3Battery::~CMX3Battery() { } void CMX3Battery::showName() { std::cout << "I am mx3's battery of meizu!\n"; } CMI1Battery::CMI1Battery() { } CMI1Battery::~CMI1Battery() { } void CMI1Battery::showName() { std::cout << "I am mi1's battery of xiaomi!\n"; } CMI2Battery::CMI2Battery() { } CMI2Battery::~CMI2Battery() { } void CMI2Battery::showName() { std::cout << "I am mi2's battery of xiaomi!\n"; } // IFactory.h #ifndef __IFACTORY_H__ #define __IFACTORY_H__ #include "IPhone.h" #include "IBattery.h" #include <string> class IFactory { public: IFactory(){}; virtual ~IFactory(){}; virtual IPhone* createPhone(std::string strName) = 0; virtual IBattery* createBattery(std::string strName) = 0; }; #endif // BatteryFactory.h #ifndef __BATTERY_FACTORY_H__ #define __BATTERY_FACTORY_H__ #include "IFactory.h" #include "IPhone.h" #include "IBattery.h" class CMXFactory:public IFactory { public: CMXFactory(); virtual ~CMXFactory(); virtual IPhone* createPhone(std::string strName); virtual IBattery* createBattery(std::string strName); }; class CMIFactory:public IFactory { public: CMIFactory(); virtual ~CMIFactory(); virtual IPhone* createPhone(std::string strName); virtual IBattery* createBattery(std::string strName); }; #endif // BatteryFactory.cpp #include "Factory.h" #include "Phone.h" #include "Battery.h" CMXFactory::CMXFactory() { } CMXFactory::~CMXFactory() { } IPhone* CMXFactory::createPhone(std::string strName) { IPhone* pPhone = NULL; if (strName == "mx1") { pPhone = new CMX1Phone(); } else if (strName == "mx2") { pPhone = new CMX2Phone(); } else if (strName == "mx3") { pPhone = new CMX3Phone(); } if (pPhone != NULL) { pPhone->showName(); } return pPhone; } IBattery* CMXFactory::createBattery(std::string strName) { IBattery* pBattery = NULL; if (strName == "mx1") { pBattery = new CMX1Battery(); } else if (strName == "mx2") { pBattery = new CMX2Battery(); } else if (strName == "mx3") { pBattery = new CMX3Battery(); } if (pBattery != NULL) { pBattery->showName(); } return pBattery; } CMIFactory::CMIFactory() { } CMIFactory::~CMIFactory() { } IPhone* CMIFactory::createPhone(std::string strName) { IPhone* pPhone = NULL; if (strName == "mi1") { pPhone = new CMI1Phone(); } else if (strName == "mi2") { pPhone = new CMI2Phone(); } if (pPhone != NULL) { pPhone->showName(); } return pPhone; } IBattery* CMIFactory::createBattery(std::string strName) { IBattery* pBattery = NULL; if (strName == "mi1") { pBattery = new CMI1Battery(); } else if (strName == "mi2") { pBattery = new CMI2Battery(); } if (pBattery != NULL) { pBattery->showName(); } return pBattery; } // main.cpp #include <iostream> #include <string> using namespace std; #include "Factory.h" int main() { std::string strName[2][4] = {"mx1","mx2","mx3","mx4","mi1","mi2","mi3","mi4"}; IFactory* pFactory[2] = {new CMXFactory(),new CMIFactory()}; for (int n = 0; n < 2; ++n) { for (int i = 0; i < 4; ++i) { IPhone* pPhone = pFactory[n]->createPhone(strName[n][i]); if (pPhone == NULL) { std::cout << "not exist phone of " << strName[n][i] << "!\n"; } delete pPhone; IBattery* pBattery = pFactory[n]->createBattery(strName[n][i]); if (pBattery == NULL) { std::cout << "not exist battery of " << strName[n][i] << "!\n"; } delete pBattery; } delete pFactory[n]; pFactory[n] = NULL; } return 0; }