• 案例分析:设计模式与代码的结构特性——高级软件工程课第六次作业


      此次作业,我选择以与“工厂”相关的三个设计模式,即简单工厂模式、工厂方法模式和抽象工厂模式为案例,进行分析。所有代码通过一个单独的C++文件来展现。

    1.简单工厂模式

       简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。事实上,它并不属于23种设计模式。

    简而言之,简单工厂模式就是就是有一个专门生产某个产品的类。

      简单工厂模式的代码案例如下:

    const int adidas = 1;
    const int nike = 2;
    //shirt抽象类
    class Shirt
    {
    public:
        virtual void Show() = 0;
    };
    
    //adidas牌shirt 
    class AdiShirt : public Shirt
    {
    public:
        void Show() { cout << "AdiShirt" << endl; }
    };
    
    //Nike牌shirt
    class NikeShirt : public Shirt
    {
    public:
        void Show() { cout << "NikeShirt" << endl; }
    };
    
    //唯一的工厂,可以生产两种品牌的shirt
    class Factory
    {
    public:
        Shirt* CreateShirt(int brand)
        {
            if (brand == adidas) //工厂内部判断 
                return new AdiShirt(); //生产adidas
            else if (brand == nike)
                return new NikeShirt(); //生产nike 
            else
                return NULL;
        }
    };

      分析封装、继承和多态:

           

       AdiShirt和NikeShirt都继承了抽象基类Shirt,并覆盖了show方法,实现了多态。Factory类的CreateShirt方法可根据输入的brand参数来确定生产Adidas牌shirt或是Nike牌Shirt

       带来的好处:这个简单工厂利用了面向对象语言中“继承”这一特性,将决定工厂的生产什么产品的决定权直接交到了客户手中,可以根据客户自己的需求,得到他们想要的最终的结果。

    2.工厂方法模式

      简单工厂模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改。这就违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。假如增加其他品牌的shirt,工厂类需要修改,如何解决?

    工厂方法模式在此时应运而生,创建一个工厂接口和创建多个工厂实现类,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

      工厂方法模式的代码案例如下:

      

    const int adidas = 1;
    const int nike = 2;
    //shirt抽象类
    class Shirt
    {
    public:
        virtual void Show() = 0;
    };
    
    //adidas牌shirt 
    class AdiShirt : public Shirt
    {
    public:
        void Show() { cout << "AdiShirt" << endl; }
    };
    
    //Nike牌shirt
    class NikeShirt : public Shirt
    {
    public:
        void Show() { cout << "NikeShirt" << endl; }
    };
    
    //工厂的抽象基类
    class Factory
    {
    public:
        virtual Shirt* CreateShirt(int brand) = 0;
    };
    
    //专门生产adidas的工厂
    class AdiFactory:public Factory
    {
    public:
        virtual Shirt* CreateShirt(int brand) {
            return new AdiShirt();
        }
    }; 
    
    //专门生产Nike的工厂
    class NikeFactory:public Factory 
    {
    public:
        virtual Shirt* CreateShirt(int brand) {
            return new NikeShirt();
        }
    };

      分析封装、继承和多态:

          

      Shirt、AdiShirt和NikeShirt类和简单工厂模式中保持一致,Factory抽象成抽象基类,且分别派生出了AdiFactory和NikeFactory。CreateShirt(int brand)为虚函数,且在两个子类中得到覆盖,即实现了多态。这种模式下,若需要扩展,只需添加新的工厂子类

    并且继承Factory这一抽象基类即可。

      带来的好处:克服了简单工厂违背开放-封闭原则的缺点,又保留了封装对象创建过程的优点,降低客户端和工厂的耦合性,“工厂方法模式”是“简单工厂模式”的进一步抽象和推广。

    3.抽象工厂模式  

      不仅可以生产Shirt,还能生产Pants。现在简单工厂模式和工厂方法模式都无法更好地完成工作。抽象工厂模式应运而生。它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。具体为,存在两个工厂(该案例中)一个专门用来生产Adidas品牌的Shirt和Pants,而另一个工厂专门用来生产Nike的Shirt和Pants。
      工厂方法模式的代码案例如下:

      

    const int adidas = 1;
    const int nike = 2;
    //shirt抽象类
    class Shirt
    {
    public:
        virtual void Show() = 0;
    };
    
    //adidas牌shirt 
    class AdiShirt : public Shirt
    {
    public:
        void Show() { cout << "AdiShirt" << endl; }
    };
    
    //Nike牌shirt
    class NikeShirt : public Shirt
    {
    public:
        void Show() { cout << "NikeShirt" << endl; }
    };
    
    //Pants抽象类
    class Pants
    {
    public:
        virtual void Show() = 0;
    };
    
    //adidas牌pants
    class AdiPants : public Pants
    {
    public:
        void Show() { cout << "AdiPants" << endl; }
    };
    
    //Nike牌pants
    class NikePants : public Pants
    {
    public:
        void Show() { cout << "NikePants" << endl; }
    };
    
    //工厂的抽象基类
    class Factory
    {
    public:
        virtual Shirt* CreateShirt(int brand) = 0;
        virtual Pants* CreatePants(int brand) = 0;
    };
    
    //专门生产adidas的工厂
    class AdiFactory :public Factory
    {
    public:
        virtual Shirt* CreateShirt(int brand) {
            return new AdiShirt();
        }
        virtual Pants* CreatePants(int brand) {
            return new AdiPants();
        }
    }; 
    
    //专门生产nike的工厂
    class NikeFactory :public Factory
    {
    public:
        virtual Shirt* CreateShirt(int brand) {
            return new NikeShirt();
        }
        virtual Pants* CreatePants(int brand) {
            return new NikePants();
        }
    };

      分析封装、继承和多态:

          

        

      相比上面两种模式,抽象工厂模式又定义了Pants基类和AdiPants、NikePants两个子类。此外对于抽象基类Factory,新增了虚函数CreatePants,并且新派生出了子类NikeFactory。在两个工厂子类——AdiFactory和NikeFactory中继承并覆盖了虚函数

    CreateShirt和CreatePants,实现了多态。每个工厂子类只负责生产自己品牌的服装——shirt或pants

      带来的好处:抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。这样模块更加清晰,每个部分都各司其职,分工明确,可维护性更好。

  • 相关阅读:
    PVID和VID与交换机端口
    IO密集型和CPU密集型区别?
    Redis回收进程是如何工作的
    索引的工作原理及其种类
    drop,delete与truncate的区别
    你用过的爬虫框架或者模块有哪些?优缺点?
    列举您使用过的Python网络爬虫所用到的网络数据包
    对cookies与session的了解?他们能单独用吗
    有用过Django REST framework吗
    Django中哪里用到了线程?哪里用到了协程?哪里用到了进程
  • 原文地址:https://www.cnblogs.com/hhssqq9999/p/11991723.html
Copyright © 2020-2023  润新知