标签:
2. 工厂方法模式
2.1工厂方法模式的定义
(1)定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类
①Product:定义了工厂方法创建对象的接口。也就是实际需要使用的产品对象的接口
②ConcreteProduct:具体的Product接口的实现对象。
③Factory(Creator):定义了工厂方法的抽象类并返回一个产品对象。
④ConcreteCreator:具体的创建器对象,该类实现和覆盖了父工厂类声明的方法。返回一个具体的Product实例
(2)思考工厂方法模式
①工厂方法模式的本质:延迟到子类来选择实现。简单工厂是直接在工厂类进行“选择实现”,而工厂方法会把这个工作延迟到子类来实现。由于工厂类依赖于抽象而不是具体的实现,从而系统更加灵活,具有更好的可维护性和可扩展性。
②工厂方法模式是简单工厂模式的进一步抽象,它保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心工厂类不再负责所有产品的创建,而是将具体的创建工作交给子类去做。这个核心类仅仅负责给具体工厂必须实现的接口,而不负责哪一个产品被实例化这种细节,这使得工厂模式可以允许系统在不修改工厂角色的情况下引用新产品。
③当系统扩展需要添加新产品对象时,仅仅需要添加一个具体产品对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好地遵守了“开闭原则”,而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
【编程实验】利用工厂方法模式实现的计算器程序
2.2 工厂模式的优点
(1)良好的封装性,代码结构清晰。客户端不需要创建具体产品对象的艰辛过程,降低模块间的耦合。
(2)其次,工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。
(3)屏蔽产品类。产品类的实现,调用者不需要关心,它只需要关心产品接口,只要接口保持不变,系统中的上层模块就不要发生变化。
(4)工厂方法模式是典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类不用关心,符合迪米特法则,也符合依赖倒置原则。
【编程实验】利用工厂方法实现导出各种类型文件
//创建型模式:工厂模式 //利用工厂模式实现导出各种类型的文件 #include <stdio.h> //导出文件接口类(抽象产品类) class CExportFileApi { public: virtual bool Export(const char* data) = 0; }; //导出文本文件(实现导出接口类) class CExportTxtFile : public CExportFileApi { public: bool Export(const char* data) { printf("Export data \"%s\" to txt file!\n",data); } }; //导出文件到数据库文件(实现导出接口的类) class CExportDBFile: public CExportFileApi { public: bool Export(const char* data) { printf("Export data \"%s\" to Database!\n",data); } }; //生成导出文件对象的工厂类(抽象类) class CExportOperate { protected: //由工厂的子类去生成具体的产品类实例 virtual CExportFileApi* factoryMethod()=0; //protected属性 public: //这个方法将客户端与具体产品类解耦 bool Export(const char* data) { CExportFileApi* api = factoryMethod(); api->Export(data); delete api; } }; //生成导出文件对象的具体工厂(实现类) class CExportTxtFileOperate : public CExportOperate { protected: CExportFileApi* factoryMethod() { return new CExportTxtFile; } }; //生成导出文件对象的具体工厂(实现类) class CExportDBOperate : public CExportOperate { protected: CExportFileApi* factoryMethod() { return new CExportDBFile; } }; int main() { //客户端调用例子(注意只依赖工厂类接口与具体工厂类,而 //与产品类及具体的产品的实现没有依赖关系,起到很好的解耦 //创建需要使用的Creator对象 CExportOperate* oper = new CExportDBOperate(); //调用输出数据的功能方法 oper->Export("abcd"); delete oper; return 0; }
2.3 工厂方法模式的使用场景
(1)工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但需要慎重考虑是否要增加一个工厂类进行管理,增加代码的复杂度
(2)需要灵活、可扩展的框架时,可以考虑采用工厂方法模式。
(3)当子类可能会很多,以后需要不断增添不同的子类实现时。
(4)如果一个类需要创建某个接口的对象,但是又不知道具体的实现时。可以选用工厂方法模式,把创建对象的工作延迟到子类中去实现。
2.4 工厂方法模式的扩展
(1) 缩小为简单工厂模式
当一个模块仅需要一个工厂类时,就只需要使用具体工厂类并使用静态方法就可以了,去掉抽象类,于是就演变成一个简单工厂类
(2)升级为多个工厂类
当一个产品类有多个具体的实现,并且每个实现类的初始化方法(包括new和对对象设置初始值)的方法都不同时,可以为每个具体实现定义相应的创建者,形成多个工厂。
标签:
原文地址:http://www.cnblogs.com/5iedu/p/5493296.html