文章链接:https://codemouse.online/archives/2020-06-01213402
工厂模式
概念:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。–《设计模型》GoF
结构
要点总结
- Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
- Factory Method模式通过面向对象的方法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
- Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。
#demo
数据导出,导出为Excel,文本,XML等
#include <iostream>
using namespace std;
class ExportFileProduct
{
public:
ExportFileProduct() {}
virtual ~ExportFileProduct() {}
virtual bool Export(string data) = 0;
};
// 保存成文件
class ExportTextProduct: public ExportFileProduct
{
public:
ExportTextProduct() {}
virtual ~ExportTextProduct() { }
virtual bool Export(string data) {
cout << "导出数据:[" << data << "]保存成文本的方式" << endl;
return true;
}
};
class ExportDBProduct: public ExportFileProduct
{
public:
ExportDBProduct() {}
virtual ~ExportDBProduct() { }
virtual bool Export(string data) {
cout << "导出数据:[" << data << "]保存数据库的方式" << endl;
return true;
}
};
class ExportFactory
{
public:
ExportFactory() {}
virtual ~ExportFactory() {}
/**
* @brief Export
* @param type 导出的类型
* @param data 具体的数据
* @return
*/
virtual bool Export(int type, string data) {
ExportFileProduct *product = nullptr;
product = factoryMethod(type);
bool ret = false;
if(product) {
ret = product->Export(data);
delete product;
} else {
cout << "没有对应的导出方式";
}
return ret;
}
protected:
virtual ExportFileProduct *factoryMethod(int type) {
ExportFileProduct *product = nullptr;
if(1 == type) {
product = new ExportTextProduct();
} else if(2 == type) {
product = new ExportDBProduct();
}
return product;
}
};
// 加一种新的导出方式:
// (1)修改原来的工厂方法
// (2)继承工厂方法去拓展
class ExportXMLProduct: public ExportFileProduct
{
public:
ExportXMLProduct() {}
virtual ~ExportXMLProduct() { }
virtual bool Export(string data) {
cout << "导出数据:[" << data << "]保存XML的方式" << endl;
return true;
}
};
class ExportPortobufferProduct: public ExportFileProduct
{
public:
ExportPortobufferProduct() {}
virtual ~ExportPortobufferProduct() { }
virtual bool Export(string data) {
cout << "导出数据:[" << data << "]保存Portobuffer的方式" << endl;
return true;
}
};
// 继承工厂的模式完成,这样就不需要改变以前的工厂代码
class ExportFactory2: public ExportFactory
{
public:
ExportFactory2() {}
virtual ~ExportFactory2() {}
protected:
virtual ExportFileProduct *factoryMethod(int type) {
ExportFileProduct *product = nullptr;
if(3 == type) {
product = new ExportXMLProduct();
} else if(4 == type) {
product = new ExportPortobufferProduct();
} else {
product = ExportFactory::factoryMethod(type);
}
return product;
}
};
int main()
{
cout << "ExportFactory" << endl;
ExportFactory *factory = new ExportFactory();
factory->Export(1, "上课人数");
factory->Export(2, "上课人数");
factory->Export(3, "上课人数");
cout << "\nExportFactory2" << endl;
ExportFactory *factory2 = new ExportFactory2();
factory2->Export(1, "上课人数");
factory2->Export(2, "上课人数");
factory2->Export(3, "上课人数");
factory2->Export(4, "上课人数");
delete factory;
delete factory2;
return 0;
}