zoukankan      html  css  js  c++  java
  • 设计模式--工厂模式(c++)

    1. 场景

        假设有如下的场景:

        卖pizza的, 可以有很多种pizza(CheesePizza, GreekPizza, PepperoniPizza),我们该如何处理它呢,当然我们可以声明一个类,类中创建每一个种类的pizza。但是这样有什么问题吗?我们没有把需要改变的部分剥离出来。软件设计的一个原则就是“是易于扩充而不是修改”,另一个是“对接口编程而不是对实现编程”。

        这里就轮到工厂模式出手了。 工厂模式有三种:

    • 简单工厂
    • 抽象工厂
    • 工厂方法

    2. 简单工厂模式

        1.1 Uml

    image

    1.2 源代码

    class Pizza 
    { 
     public: 
         Pizza(){}; 
        virtual ~Pizza(){};
    
        virtual void MakePizza() = 0; 
    };
    
     class CheesePizza : public Pizza 
    { 
     public: 
        CheesePizza(){}; 
        ~CheesePizza(){};
    
     void MakePizza() 
    { 
        cout << "make cheese pizza" <<endl; 
    } 
    };
    
    class GreekPizza : public Pizza 
    { 
    public: 
        GreekPizza(){}; 
        ~GreekPizza(){};
    
        void MakePizza() 
        { 
            cout << "make greek pizza" <<endl; 
        }
    
    };
    
    class PepperoniPizza : public Pizza 
    { 
    public: 
        PepperoniPizza(){}; 
        ~PepperoniPizza(){};
    
        void MakePizza() 
        { 
            cout << "make peperoni pizza" <<endl; 
        }
    
    };
    
    enum PIZZA_TYPE 
    { 
        PIZZA_TYPE_CHEESE = 0, 
        PIZZA_TYPE_GREEK, 
        PIZZA_TYPE_PEPPERONI 
    };
    
    class PizzaFactory 
    { 
    public: 
        PizzaFactory(){}; 
        ~PizzaFactory(){};
    
        static shared_ptr<Pizza> createPizza(PIZZA_TYPE pizzaType) 
        { 
            switch (pizzaType) 
            { 
            case PIZZA_TYPE_CHEESE: 
                return shared_ptr<Pizza>(new CheesePizza()); 
            case PIZZA_TYPE_GREEK: 
                return shared_ptr<Pizza>(new GreekPizza()); 
            case PIZZA_TYPE_PEPPERONI: 
                return shared_ptr<Pizza>(new PepperoniPizza()); 
            default: 
                return shared_ptr<Pizza>(new PepperoniPizza()); 
            } 
        } 
    };

    测试代码

    int _tmain(int argc, _TCHAR* argv[]) 
    {
    
        shared_ptr<Pizza> cheesePizza = PizzaFactory::createPizza(PIZZA_TYPE_CHEESE); 
        shared_ptr<Pizza> greekPizza = PizzaFactory::createPizza(PIZZA_TYPE_GREEK); 
        shared_ptr<Pizza> pepperoniPizza = PizzaFactory::createPizza(PIZZA_TYPE_PEPPERONI);
    
        cheesePizza->MakePizza(); 
        greekPizza->MakePizza(); 
        pepperoniPizza->MakePizza(); 
        return 0; 
    }

    这样写好什么好处呢?

    1. .静态工厂方法统一管理对象的创建
    2. 静态工厂方法推迟了产品的实例化。

    这样写的缺点是什么呢?

      缺点就是在增加新的类型时,需要修改工厂类。这违反了开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是需要更高级的工厂方法模式。

    2. 工厂方法模式

        工厂方法模式: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

        当然从代码的角度就是其实就是把 PizzaFactory 抽象出来,用子类来实现。

    class PizzaFactory 
    { 
    public: 
        PizzaFactory(){}; 
        ~PizzaFactory(){};
    
        virtual Pizza* createPizza()  = 0;
    };
    
    class PizzaFactoryCheese : public PizzaFactory
    {
    public:
         CheesePizza*    createPizza() { return new CheesePizza; }
    }
    
    class PizzaFactoryGreek : public PizzaFactory
    {
    public:
         GreekPizza*    createPizza() { return new GreekPizza; }
    }

       注意:由于此时PizzaFactory的createPizza()为虚函数,因此不能使用static修饰符。

       工厂方法模式也有缺点,每增加一种产品,就需要增加一个对象的工厂。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。

       至此,貌似有简单工厂模式和工厂方法模式所有问题都可以应付了,但是,如果生意扩大了,除了Pizza又做Hamburger了,怎么办? 于是抽象工厂模式出现了。

    3. 抽象工厂

        抽象工厂和工厂方法的主要区别是工厂方法使用继承来创建对象,而抽象工厂是使用组合。

    image 

    例子代码如下:

    class Burger
    { 
     public: 
         Burger(){}; 
        virtual ~Burger(){};
    
        virtual void MakeBurger() = 0; 
    };
    
     class KfcBurger : public Burger
    { 
     public: 
        KfcBurger (){}; 
        ~KfcBurger (){};
    
     void MakeBurger() 
    { 
        cout << "make KFC Burget" <<endl; 
    } 
    };
    
     class McdBurger : public Burger
    { 
     public: 
        McdBurger (){}; 
        ~McdBurger (){};
    
     void MakeBurger() 
    { 
        cout << "make McD Burget" <<endl; 
    } 
    };
    
    class CoreFactory
    {
        virtual Pizza* MakePizza() = 0;
        virtual Burger* MakeBurger() = 0;
    }
    
    class FactoryA : public CoreFactory
    {
     public:
          Pizza* MakePizza() {return new CheesePizza;}
          Burger* MakeBurger() {return new KfcBurger;}
    }
    
    class FactoryB : public CoreFactory
    {
     public:
          Pizza* MakePizza() {return new GreekPizza;}
          Burger* MakeBurger() {return new McdBurger;}
    }
  • 相关阅读:
    System.nanoTime()的使用
    只为高效、流畅开发 —— 码云企业版 3.0 倾情上线
    不自律的人,下场都很惨
    刘德:小米已投89家生态链企业 有品要做百亿电商平台(本质上是是利用了小米的大火炉的余热,但也有反向的正面作用)
    英雄无敌手游(战争纪元云中城,还可以骑龙,绝美)
    openFrameworks 是一个旨在助力你进行开创性工作的开源 C++ 工具箱(是很多其它类库的组合)
    Core开发-MVC 使用dotnet 命令创建Controller和View
    Ant Table组件
    web性能优化
    scss + react + webpack + es6
  • 原文地址:https://www.cnblogs.com/haba/p/3415860.html
Copyright © 2011-2022 走看看