• C++设计模式之抽象工厂模式


    抽象工厂概述

    在抽象工厂模式中,定义了一个抽象工厂类,它提供了创建一组对象的接口,这种模式适合解决多个不同产品系列的问题,抽象工厂定义如下:

    抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类,其基本UML类图如下:
    这里写图片描述

    在抽象工厂模式结构图中包含如下几个角色:

    • AbstractFactory(抽象工厂):它声明了一组用于创建不同类别产品的抽象方法,每一个方法对应一类产品。

    • ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成具体产品。

    • AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
    • ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

    在抽象工厂中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或者具体类.

    模拟场景

    我们都知道富士康是一家电子代工厂,它可以代工生产各类电子产品,比如电视、手机、冰箱等。当设计厂家提交订单给富士康时,富士康会为各个厂家搭建各自的生产线,现在模拟其生产过程,UML设计图如下:

    这里写图片描述

    uml类图说明:

    1. CAbsFactory类中的抽象接口代表了富士康工厂具备的生产能力;
    2. TCLProduct类和XiaomiProduct类代表TCL和小米设计厂家;
    3. CAbstractPhone类代表手机具备的公共特征;
    4. CAbstractTV类代表电视机具备的公共特征;

    具体代码:

    主体代码:

    #include "stdafx.h"
    using namespace std;
    
    //手机基类
    class CAbstractPhone
    {
    public:
        CAbstractPhone(){}
        virtual ~CAbstractPhone(){}
        //身份识别
        virtual void GetPhoneID()= 0;
    };
    
    //电视基类
    class CAbstractTV
    {
    public:
        CAbstractTV(){}
        virtual ~CAbstractTV(){}
        //身份识别
        virtual void GetTVID()= 0;
    };
    
    //子类: TCL电视机
    class TCLTV:public CAbstractTV
    {
    public:
        TCLTV(){cout <<"Create TCL TV."<<endl;}
        ~TCLTV(){}
        virtual void GetTVID()
        {
            cout << "I am TCL TV." <<endl;
        }
    };
    //子类: TCL手机
    class TCLPhone:public CAbstractPhone
    {
    public:
        TCLPhone(){cout <<"Create TCL phone."<< endl;}
        ~TCLPhone(){}
        virtual void GetPhoneID()
        {
            cout << "I am TCL phone" <<endl;
        }
    };
    
    
    //子类: 小米电视机
    class XiaomiTV:public CAbstractTV
    {
    public:
        XiaomiTV(){cout <<"Create Xiaomi TV."<<endl;}
        ~XiaomiTV(){}
        virtual void GetTVID()
        {
            cout << "I am Xiaomi TV" <<endl;
        }
    };
    //子类: 小米手机
    class XiaomiPhone:public CAbstractPhone
    {
    public:
        XiaomiPhone(){cout <<"Create Xiao phone."<< endl;}
        ~XiaomiPhone(){}
        virtual void GetPhoneID()
        {
            cout << "I am Xiaomi phone" <<endl;
        }
    };
    
    //代工厂的生产能力
    class CAbsFactory
    {
    public:  
        virtual CAbstractTV* CreateTV()=0;
        virtual CAbstractPhone* CreatePhone()=0;
    };
    
    //TCL电子设备生产线
    class TCLProduct:public CAbsFactory
    {
    public:
        virtual CAbstractTV* CreateTV()
        {
          return new TCLTV;
        }
        virtual CAbstractPhone* CreatePhone()
        {
            return new TCLPhone;
        }
    };
    
    //小米电子设备生产线
    class XiaomiProduct:public CAbsFactory
    {
    public:
        virtual CAbstractTV* CreateTV()
        {
             return new XiaomiTV;
        }
        virtual CAbstractPhone* CreatePhone()
        {
            return new XiaomiPhone;
        }
    };
    

    测试代码:

    int _tmain(int argc, _TCHAR* argv[])
    {
    
        //生产TCL产品
        CAbsFactory* pTclFactory = new TCLProduct();
        //生产手机
        CAbstractPhone* pPhone = pTclFactory->CreatePhone();
        //生产电视
        CAbstractTV* pTV = pTclFactory->CreateTV();
        //身份验证
        pPhone->GetPhoneID();
        pTV->GetTVID();
    
        cout <<"
    ";
        //生产小米产品
        CAbsFactory* pXiaomiFactory = new XiaomiProduct();
        //生产小米手机
        CAbstractPhone* pXiaoPhone = pXiaomiFactory->CreatePhone();
        //生产小米电视
        CAbstractTV* pXiaoTV = pXiaomiFactory->CreateTV();
        //身份验证
        pXiaoPhone->GetPhoneID();
        pXiaoTV->GetTVID();
    
        SAFE_DELETE_PTR(pTclFactory);
        SAFE_DELETE_PTR(pPhone);
        SAFE_DELETE_PTR(pTV);
    
        SAFE_DELETE_PTR(pXiaomiFactory);
        SAFE_DELETE_PTR(pXiaoPhone);
        SAFE_DELETE_PTR(pXiaoTV);
    }

    运行结果:

    这里写图片描述

    抽象工厂总结

    优点:

    1. 抽象工厂在新增其他的具体工厂类符合“开放扩展-关闭修改”原则;比如新增华为品牌手机和电视,只需要新增具体的工厂类和产品类即可,不需要修改其他代码;
    2. 创建具体产品实例过程和客户端分离,且客户端是面对抽象接口进行编程,易于进行整体更换;

    缺点:

    1. 抽象工厂最大的不足就是新增抽象接口,以完成某个额外的产品;比如让富士康增加生成汽车的接口,对整体系统影响很大;比如需要在抽象工厂类中增加生成汽车接口,甚至需要修改具体工厂类;

    适用场景:

    1. 抽象工厂适合解决需要“创建多个种类的产品”的场合;

    资料参考:http://blog.csdn.net/lovelion/article/details/17517213

  • 相关阅读:
    json转MAP
    责任链模式
    单例模式
    代理模式
    策略模式
    mysql触发器的使用
    Java 中的日期和时间
    MySQL插入数据前检测唯一性
    java字符串转为Map类型:split()方法的应用
    java Socket实例
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468213.html
Copyright © 2020-2023  润新知