之前提到了简单工厂模式,其核心思想是客户端与接口完全解耦。
而工厂模式是对简单工厂的进一步提炼与总结。
从封装的角度来讲,我们希望导出的数据数据的业务功能创建ExportFileApi的具体实例,目前只知道接口,该怎么办?
答:让子类决定实例化某一个类,实现类的实例化的延迟。
工厂模式图大致如下:

话不多说,先上代码,注意看注释:
- #include
- #include
- using namespace std;
-
- class ExportFileApi {
- public:
- virtual bool exportData(string data) = 0;
- protected:
- ExportFileApi() {}
- };
-
- //具体化子类
- class ExportTextFile :public ExportFileApi {
- public:
- bool exportData(string data) {
- cout << "正在导出数据" << data << "到csv文件" << endl;
- return true;
- }
- };
-
- //生成数据到数据库
- class ExportDB :public ExportFileApi {
- public:
- bool exportData(string data) {
- cout << "正在导出数据" << data << "数据库" << endl;
- return true;
- }
- };
-
- //实现一个ExportOperate,导出数据的业务功能
- //这也是接口,具体的工作交给子类实现
- class ExportOperate {
- public:
- bool exportData(string data) {
- ExportFileApi* pApi = factoryMethod();
- return pApi->exportData(data);
- }
- protected:
- virtual ExportFileApi* factoryMethod() = 0;
- };
-
- //具体的实现对象,完成导出工作
- class ExportTextFileOperate :public ExportOperate {
- //不想让外部来访问
- protected:
- ExportFileApi* factoryMethod() {
- return new ExportTextFile();
- }
- };
-
- class ExportDBOperate :public ExportOperate {
- protected:
- ExportFileApi* feactoryMethod() {
- return new ExportDB;
- }
- };
-
- int main() {
- ExportOperate* pOperate = new ExportTextFileOperate();
- pOperate->exportData("666");
- return 0;
- }
对于此例的UML工厂模式的UML:

依赖注入:应用程序依赖容器创建并注入它所需要的外部资源
控制反转:容器控制应用程序,由容器反向的向Application注入程序所需要的

降低A和B的耦合,交由IOC容器去管理。
同时这种思想适用于很多个对象之间的管理,就比如一个老师要管理50甚至上百个学生,需要一个点名册,记录学号等信息,来管理学生。这个点名册就是IOC。

具体看一个例子:
- #include
- #include
- #include
- #include
- #include
- using namespace std;
-
- template <class T>
- class IocContainer {
- public:
- IocContainer() {}
- ~IocContainer()
- {
-
- }
-
- //注册需要创建对象的构造函数,通过一个唯一的标识,以便于以后查找
- template<class Drived>
- void RegisterType(string strKey) {
- std::function
function = [] {return new Drived(); }; - RegisterType(strKey, function);
- }
-
- //根据唯一的标识查找对应的构造函数
- T* Resolve(string strKey) {
- if (m_createMap.find(strKey) == m_createMap.end()) {
- return nullptr;
- }
- std::function
function = m_createMap[strKey]; - return function();
- }
-
- //创建智能指针
- std::shared_ptr
ResolveShared(string strKey) { - T* ptr = Resolve(strKey);
- return std::shared_ptr
(ptr); - }
- private:
- void RegisterType(string strKey, std::function
creator) { - if (m_createMap.find(strKey) != m_createMap.end()) {
- throw std::invalid_argument("已经存在这个key了");
- }
- m_createMap.emplace(strKey, creator);
- }
- private:
- map
>m_createMap; - };
-
-
- struct ICar {
- virtual ~ICar() {}
- virtual void test()const = 0;
- };
-
- struct Bus:ICar
- {
- Bus() {}
- void test()const { cout << "Bus test" << endl; }
- };
-
- struct Track :ICar
- {
- Track() {}
- void test()const { cout << "Track test" << endl; }
- };
-
- int main() {
- IocContainer
carIOC; - carIOC.RegisterType
("bus"); - carIOC.RegisterType
-
- std::shared_ptr
bus = carIOC.ResolveShared("bus"); - bus->test();
-
- std::shared_ptr
track = carIOC.ResolveShared("track"); - track->test();
-
- return 0;
- }

何时选用工厂模式?