工厂模式

大耗子 2020年06月01日 187次浏览

文章链接: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;
}