zoukankan      html  css  js  c++  java
  • 【设计模式】Abstract Factory模式

    抽象工厂模式是工厂方法模式的进一步强化。当工厂函数仅仅须要产生一种类型的产品(全部产品都继承自同一抽象基类时,使用工厂方法模式就可以。

    可是。当用户程序须要创建多种类型的产品,而这些产品又有一定的内在联系,那么就要用到抽象工厂模式了。抽象工厂模式的UML图例如以下所看到的:



    AbstractProductA和AbstractProductB是两种不同类型的抽象产品,每种类中的抽象以下又有两种不同类型的实现。

    两个详细的工厂ConcreteFactory1和ConcreteFactory2负责生产每种抽象产品下的一个详细产品。

    这种关系看起来比較复杂,以下通过一个样例来说明。一下是用C++编写的模拟抽象工厂模式的样例。

    #include <iostream>
    #include <string>
     
    using namespace std;
     
    // 笔记本抽象类
    class Notebook {
    public:
        // 全部笔记本拥有的共同接口
        virtual void Work() = 0;
    };
     
    // 华硕笔记本详细类
    class ASUSNotebook : public Notebook {
    public:
        void Work()
        {
            cout << "ASUS notebook working..." << endl;
        }
    };
     
    // 联想笔记本详细类
    class LenovoNotebook : public Notebook {
    public:
        void Work()
        {
            cout << "Lenovo notebook working..." << endl;
        }
    };
     
    // 台式机抽象类
    class Desktop {
    public:
        // 全部台式机拥有的共同接口
        virtual void Work() = 0;
    };
     
    // 华硕台式机详细类
    class ASUSDesktop : public Desktop {
    public:
        void Work()
        {
            cout << "ASUS desktop working..." << endl;
        }
    };
     
    // 联想台式机详细类
    class LenovoDesktop : public Desktop {
    public:
        void Work()
        {
            cout << "Lenovo desktop working..." << endl;
        }
    };
     
    // 抽象工厂
    class AbstractFactory {
    public:
        virtual Notebook* CreateNotebook() = 0; // 生产台式机的接口
        virtual Desktop* CreateDesktop() = 0;   // 生产笔记本的接口
    };
     
    // 华硕工厂
    class FactoryOfASUS : public AbstractFactory {
    public:
        // 华硕生产的笔记本
        Notebook* CreateNotebook()
        {
            return new ASUSNotebook();
        }
     
        // 华硕生产的台式机
        Desktop* CreateDesktop()
        {
            return new ASUSDesktop();
        }
    };
     
    // 联想工厂
    class FactoryOfLenovo : public AbstractFactory {
    public:
        // 联想生产的台式机
        Notebook* CreateNotebook()
        {
            return new LenovoNotebook();
        }
     
        // 联想生产的笔记本
        Desktop* CreateDesktop()
        {
            return new LenovoDesktop();
        }
    };
     
    int main()
    {
        // 注意,用户仅仅拥有抽象接口
        AbstractFactory *factory = new FactoryOfASUS(); // 实例化生产华硕电脑的工厂
        //AbstractFactory *factory = new FactoryOfLenovo(); // 实例化生产联想电脑的工厂
     
        // 抽象产品类。不同的品牌是通过多态性质体现的
        Notebook *myNotebook;
        Desktop *myDesktop;
     
        myNotebook = factory->CreateNotebook();
        myDesktop = factory->CreateDesktop();
     
        myNotebook->Work();
        myDesktop->Work();
     
        // 别忘了删除指针
        delete factory;
        delete myNotebook;
        delete myDesktop;
     
        system("pause");
        return 0;
    }

    执行结果:


    在这个样例中,有两类抽象产品:笔记本Notebook和台式机Desktop。在它们以下又相应了详细的品牌。到底产生哪类品牌的电脑是由详细的工厂对象完毕的。对于用户代码而言,它们仅仅须要实例化详细品牌的工厂,然后通过工厂产生Notebook和Desktop对象就可以。当用户须要更换品牌时,仅仅须要改动第97、99两行代码就可以,例如以下所看到的:

    //AbstractFactory *factory = new FactoryOfASUS();   // 实例化生产华硕电脑的工厂
    AbstractFactory *factory = new FactoryOfLenovo();   // 实例化生产联想电脑的工厂

    改动后的执行结果:


    抽象工厂模式的长处就是便于交换产品系列。在上面的样例中。仅仅须要改动一处用户代码便能够更换整个电脑产品系列的品牌。

    其次,用户代码包括的都是指向抽象基类的指针,详细的产品通过多态性加以差别,这使得用户代码依赖于抽象接口而不依赖于详细的类,添加了代码的灵活度。

    參考:

    《大话设计模式》文章15章

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    有序表的合并---顺序表实现
    有序表的合并---链表实现
    双向链表操作
    有序表的合并-用链表操作
    C语言单链表操作
    c语言顺序表操作
    c语言 取余 % 和除法 / 的应用技巧 (在取位数方面的)
    JS打印表格(HTML定义格式)
    富文本编辑器(php)
    利用formdata异步上传图片并预览图片
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4680997.html
Copyright © 2011-2022 走看看