工厂设计模式和抽象工厂设计模式

工厂设计模式

1、定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。 ——《设计模式》GoF

2、代码实现

代码背景:实现一个导出数据的接口,让客户选择数据的导出方式

#include <string>
// 实现导出数据的接口, 导出数据的格式包含 xml,json,文本格式txt 后面可能扩展excel格式csv
class IExport {
public:
    virtual bool Export(const std::string &data) = 0;
    virtual ~IExport(){}
};

class ExportXml : public IExport {
public:
    virtual bool Export(const std::string &data) {
        
        //...
        //Xml方式输出

        return true;
    }
};

class ExportJson : public IExport {
public:
    virtual bool Export(const std::string &data) {

        //...
        //Json方式输出

        return true;
    }
};

class ExportTxt : public IExport {
public:
    virtual bool Export(const std::string &data) {

        //...
        //Txt方式输出

        return true;
    }
};

//==========================================上面是干活的类,下面是对应的工厂类==================================================

class IExportFactory {
public:
    IExportFactory() {
        _export = nullptr;
    }

    virtual ~IExportFactory() {
        if (_export) {
            delete _export;
            _export = nullptr;
        }
    }

    //调用对象自己的的Export函数
    bool Export(const std::string &data) {
        if (_export == nullptr) {
            _export = NewExport();
        }
        return _export->Export(data);
    }
protected:
    virtual IExport * NewExport(/* ... */) = 0;   //工厂模式的优点是隐藏了创建对象时的复杂过程,而外界直接用创建好的对象就可以了
private:
    IExport* _export;
};

class ExportXmlFactory : public IExportFactory {
protected:
    virtual IExport * NewExport(/* ... */) {   
        // 可能有其它操作,或者许多参数
        IExport * temp = new ExportXml();
        // 可能之后有什么操作
        return temp;
    }
};
class ExportJsonFactory : public IExportFactory {
protected:
    virtual IExport * NewExport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IExport * temp = new ExportJson;
        // 可能之后有什么操作
        return temp;
    }
};
class ExportTxtFactory : public IExportFactory {
protected:
    IExport * NewExport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IExport * temp = new ExportTxt;
        // 可能之后有什么操作
        return temp;
    }
};


int main () {
    IExportFactory * Txt_factory = new ExportTxtFactory();
    Txt_factory->Export("hello world");
    return 0;
}

代码分析:

  • 首先创建一个抽象接口类,规范代码;所有新扩展的接口输出类都继承这个接口,并实现如何输出数据的功能
  • 创建一个总的抽象工厂类,再创建接口输出类对应的工厂类,并继承这个抽象工厂类
  • 每个接口输出方式对应的工厂类中:实现接口输出类的创建过程,因为创建对象过程比较复杂,就交给工厂创建(工厂就是用来创建对象的)
  • 创建出来的对象可以选择返回给用户,也可以选择调用这个对象里面的函数完成特定的功能

总结:工厂就是用来创建对象的,尤其是创建需要很多初始化参数的对象,让外界不用关心创建过程只关心使用

3、要点

  • 解决创建过程比较复杂,希望对外隐藏这些细节的场景

    • 比如连接池、线程池
  • 隐藏对象真实类型(用到了多态)

  • 对象创建会有很多参数来决定如何创建,而工厂就干了这个活,外界直接用创建好的对象就可以了

4、本质

  • 延迟到子类来选择实现---->子类指的是工厂子类,想得到什么对象,只要创建对应的工厂类对象就能得到想要的对象

5、结构图

工厂设计模式

抽象工厂设计模式

1、定义

提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。——《设计模式》GoF

2、代码实现

代码背景:实现一个拥有导出导入数据的接口,让客户选择数据的导出导入方式;

#include <string>
// 实现导入、导出数据的接口,导入、导出数据的格式包含 xml,json,文本格式txt 后面可能扩展excel格式csv
class IExport {
public:
    virtual bool Export(const std::string &data) = 0;
    virtual ~IExport(){}
};

class ExportXml : public IExport {
public:
    virtual bool Export(const std::string &data) {
        return true;
    }
};

class ExportJson : public IExport {
public:
    virtual bool Export(const std::string &data) {
        return true;
    }
};

class ExportTxt : public IExport {
public:
    virtual bool Export(const std::string &data) {
        return true;
    }
};

//==========================================上面是导出==================================================

class IImport {
public:
    virtual bool Import(const std::string &data) = 0;
    virtual ~IImport(){}
};

class ImportXml : public IImport {
public:
    virtual bool Import(const std::string &data) {
        return true;
    }
};

class ImportJson : public IImport {
public:
    virtual bool Import(const std::string &data) {
        return true;
    }
};

class ImportTxt : public IImport {
public:
    virtual bool Import(const std::string &data) {
        return true;
    }
};

//==========================================上面是导入==================================================

class IDataApiFactory {
public:
    IDataApiFactory() {
        _export = nullptr;
        _import = nullptr;
    }
    virtual ~IDataApiFactory() {
        if (_export) {
            delete _export;
            _export = nullptr;
        }
        if (_import) {
            delete _import;
            _import = nullptr;
        }
    }

    bool Export(const std::string &data) {
        if (_export == nullptr) {
            _export = NewExport();  //当子类重写了NewExport,调用的就是子类的了
        }
        return _export->Export(data);
    }
    bool Import(const std::string &data) {
        if (_import == nullptr) {
            _import = NewImport();  //当子类重写了NewExport,调用的就是子类的了
        }
        return _import->Import(data);
    }
protected:
    virtual IExport * NewExport(/* ... */) = 0;
    virtual IImport * NewImport(/* ... */) = 0;
private:
    IExport *_export;
    IImport *_import;
};

class XmlApiFactory : public IDataApiFactory {
protected:
    virtual IExport * NewExport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IExport * temp = new ExportXml;
        // 可能之后有什么操作
        return temp;
    }
    virtual IImport * NewImport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IImport * temp = new ImportXml;
        // 可能之后有什么操作
        return temp;
    }
};

class JsonApiFactory : public IDataApiFactory {
protected:
    virtual IExport * NewExport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IExport * temp = new ExportJson;
        // 可能之后有什么操作
        return temp;
    }
    virtual IImport * NewImport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IImport * temp = new ImportJson;
        // 可能之后有什么操作
        return temp;
    }
};
class TxtApiFactory : public IDataApiFactory {
protected:
    virtual IExport * NewExport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IExport * temp = new ExportTxt;
        // 可能之后有什么操作
        return temp;
    }
    virtual IImport * NewImport(/* ... */) {
        // 可能有其它操作,或者许多参数
        IImport * temp = new ImportTxt;
        // 可能之后有什么操作
        return temp;
    }
};



int main () {
    IDataApiFactory *factory = new TxtApiFactory();
    factory->Import("hello world");
    factory->Export("hello world");
    return 0;
}



代码分析:

  • 和普通的工厂类不同的是一个工厂类既可以创建对应的导出对象,也能创建导入对象
  • 抽象工厂设计模式:让有关联的类可以放在一个工厂类中,需要的时候就可以创建对应的对象
    • 在本例中,Txt方式的导入、导出是两个功能,但是都是和Txt相关的
    • 可以把和Txt功能相关的类都放进Txt工厂中,需要某个Txt功能的时候,就调用相关的函数创建对象就行
    • 根据具体业务需求,可以创建完返回该对象,也可以直接调用该对象的成员函数实现某些功能

总结:抽象工厂设计模式的扩展性更强,可用于扩展同一类型下的多种功能(例:Txt方式的导入、导出、转码等)

3、结构图

抽象工厂设计模式

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值