NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
## 工厂方法模式定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method 使一个类的实例化延迟到其子类。 ## 工厂方法模式功能 工厂方法模式的主要功能是让父类在不知道具体实现的情况下,完成自身的功能调用,而具体的实现延时到子类来实现。 这样在设计的时候,不用考虑具体的实现,需要某个对象,把它通过工厂方法返回就好了,在使用这些对象实现功能的时候还是通过接口来操作。 ```cpp #include <iostream> #include <memory> /** * 导出文件对象的接口 */ class ExportFileApi { public: virtual bool exportFile(const std::string& data) = 0; virtual ~ExportFileApi() {} }; /** * 导出文本文件格式的对象 */ class ExportTxtFile : public ExportFileApi { public: bool exportFile(const std::string& data) override { std::cout << "export data: " << data << " to txt" << std::endl; return true; } }; /** * 导出数据库备份文件格式的对象 */ class ExportDBFile : public ExportFileApi { public: bool exportFile(const std::string& data) override { std::cout << "export data: " << data << " to DB" << std::endl; return true; } }; /** * 实现导出数据的业务功能对象 */ class ExportFileOperate { public: bool exportFile(const std::string& data) { std::shared_ptr<ExportFileApi> ptr = factoryMethod(); return ptr->exportFile(data); } virtual ~ExportFileOperate() {} protected: virtual std::shared_ptr<ExportFileApi> factoryMethod() = 0; }; /** * 具体的创建器实现对象,实现创建导出文本文件格式的对象 */ class ExportTxtFileOperate : public ExportFileOperate { protected: std::shared_ptr<ExportFileApi> factoryMethod() override { std::shared_ptr<ExportFileApi> ptr(new ExportTxtFile()); return ptr; } }; /** * 具体的创建器实现对象,实现创建导出数据库备份文件格式的对象 */ class ExportDBFileOperate : public ExportFileOperate { protected: std::shared_ptr<ExportFileApi> factoryMethod() override { std::shared_ptr<ExportFileApi> ptr(new ExportDBFile()); return ptr; } }; void test() { std::shared_ptr<ExportFileOperate> ptr(new ExportDBFileOperate()); ptr->exportFile("test"); } int main(int argc, char** argv) { test(); return 0; } ``` 输出结果: ``` export data: test to DB ``` ## 参数化工厂方法 ```cpp #include <iostream> #include <memory> /** * 导出文件对象的接口 */ class ExportFileApi { public: virtual bool exportFile(const std::string& data) = 0; virtual ~ExportFileApi() {} }; /** * 导出文本文件格式的对象 */ class ExportTxtFile : public ExportFileApi { public: bool exportFile(const std::string& data) override { std::cout << "export data: " << data << " to txt" << std::endl; return true; } }; /** * 导出数据库备份文件格式的对象 */ class ExportDBFile : public ExportFileApi { public: bool exportFile(const std::string& data) override { std::cout << "export data: " << data << " to DB" << std::endl; return true; } }; enum class Type { TxtType, // 文本类型 DbType, // 数据库类型 XmlType, // XML类型 }; /** * 实现导出数据的业务功能对象 */ class ExportFileOperate { public: bool exportFile(Type type, const std::string& data) { std::shared_ptr<ExportFileApi> ptr = factoryMethod(type); return ptr->exportFile(data); } virtual ~ExportFileOperate() {} protected: virtual std::shared_ptr<ExportFileApi> factoryMethod(Type type) { std::shared_ptr<ExportFileApi> ptr = nullptr; if (type == Type::TxtType) ptr.reset(new ExportTxtFile()); else if (type == Type::DbType) ptr.reset(new ExportDBFile()); return ptr; } }; /** * 导出XML文件格式的对象 */ class ExportXMLFile : public ExportFileApi { public: bool exportFile(const std::string& data) override { std::cout << "export data: " << data << " to XML" << std::endl; return true; } }; /** * 扩展ExportFileOperate对象,加入可以导出XML文件 */ class ExportFileOperate2 : public ExportFileOperate { protected: virtual std::shared_ptr<ExportFileApi> factoryMethod(Type type) { // 可以全部覆盖,也可以选择自己感兴趣的覆盖 // 这里只想添加自己感兴趣的实现,其他的不管 std::shared_ptr<ExportFileApi> ptr = nullptr; if (type == Type::XmlType) ptr.reset(new ExportXMLFile()); else ptr = ExportFileOperate::factoryMethod(type); // 其它让父类来实现 return ptr; } }; void test1() { std::cout << "test1" << std::endl; std::shared_ptr<ExportFileOperate> ptr(new ExportFileOperate()); ptr->exportFile(Type::TxtType, "test"); ptr->exportFile(Type::DbType, "test"); } void test2() { std::cout << "test2" << std::endl; std::shared_ptr<ExportFileOperate2> ptr(new ExportFileOperate2()); ptr->exportFile(Type::TxtType, "test"); ptr->exportFile(Type::DbType, "test"); ptr->exportFile(Type::XmlType, "test"); } int main(int argc, char** argv) { test1(); test2(); return 0; } ``` 输出结果: ``` test1 export data: test to txt export data: test to DB test2 export data: test to txt export data: test to DB export data: test to XML ``` ## 工厂方法模式的本质 **延迟到子类来选择实现** 工厂方法模式中的工厂方法,在真正实现的时候,一般是先选择具体使用哪一个具体的产品实现对象,然后创建这个具体产品对象的示例,最后就可以返回去了,也就是说,工厂方法本身并不会去实现产品接口,具体的产品实现是已经写好了的,工厂方法只要去选择实现就好了。 ## 工厂方法和简单工厂模式不同点 从本质上讲,两者非常类似,在具体实现上都是“选择实现”。但是也存在不同点,简答工厂是直接在工厂类里面直接进行“选择实现”;而工厂方法会把这个工作延时到子类来实现,工厂类里面使用工厂方法的地方是依赖于抽象而不是具体的实现,从而使系统更加灵活,具有更好的维护性和可扩展性。将上面代码的ExportFileOperate类的下面这部分代码去掉就是简单工厂了 ```cpp /** * 实现导出数据的业务功能对象 */ class ExportFileOperate { // public: // bool exportFile(Type type, const std::string& data) // { // std::shared_ptr<ExportFileApi> ptr = factoryMethod(type); // return ptr->exportFile(data); // } // virtual ~ExportFileOperate() {} protected: virtual std::shared_ptr<ExportFileApi> factoryMethod(Type type) { std::shared_ptr<ExportFileApi> ptr = nullptr; if (type == Type::TxtType) ptr.reset(new ExportTxtFile()); else if (type == Type::DbType) ptr.reset(new ExportDBFile()); return ptr; } }; ```