工厂模式—C++代码demo解释

一、是什么

  • 工厂模式解决的主要问题是,将原来分布在各个地方的对象创建的过程单独抽离出来,交付给工厂来处理,其它地方想要使用直接调用工厂方法获取对象即可
  • 我们可以抽象出一些类的公共接口来形成抽象父类或者接口,这样就可以通过声明一个指向父类的指针,来指向子类的实际实现,达到多态的目的

二、优缺点

  • 优点
    • 定义创建对象的接口,封装了对象创建的过程
    • 使具体化类的工作延迟到了子类之中
  • 缺点
    • 程序员必须知道子类的名字,当子类非常多的时候命名是一件非常麻烦的事情
    • 在父类之中并不知道具体要实例化哪一个具体的子类

三、工厂模式的分类和介绍

  • 工厂模式主要分为以下三类

    • 简单工厂

      • 设定场景:去饭店点菜,有各种菜肴,需要给这个饭店建模

        #include <iostream>
        using namespace  std;
        
        //定义一个抽象的基类
        class hotel
        {
        public:
            virtual ~hotel(){};
            virtual void order()=0;//点餐,是一个接口类
        };
        
        //接下来定义继承基类的子类
        class fruit:public hotel
        {
        public:
            void order()
            {
                cout<<"吃水果"<<endl;
            }
        };
        class beef:public hotel
        {
        public:
            void order()
            {
                cout<<"吃牛肉"<<endl;
            }
        };
        class chicken:public hotel
        {
        public:
            void order()
            {
                cout<<"吃鸡肉"<<endl;
            }
        };
        
        enum HotelType
        {
            Fruit,
            Beef,
            Chicken
        };
        class Factory
        {
        public:
            hotel* CrateHotel(HotelType type)
            {
                switch(type)
                {
                    case Fruit:
                        return new fruit(); //将子类的指针赋值给父类,实现多态
                        break;
                    case Beef:
                        return new beef();
                        break;
                    case Chicken:
                        return new chicken();
                        break;
                }
            }
        };
        
        int main() {
            Factory factory;
            factory.CrateHotel(Beef)->order();
            factory.CrateHotel(Beef)->order();
            factory.CrateHotel(Fruit)->order();
        
            return 0;
        }
        

在这里插入图片描述

  • 工厂方法

    • 设定场景:假设最近客人增加,需要独立每个菜品,每个生产线只生产一种菜肴,及给每个子类提供一个工厂

      #include <iostream>
      using namespace  std;
      
      //定义一个抽象的基类
      class hotel{
      public:
          virtual ~hotel(){};
          virtual void order()=0;//点餐,是一个接口类
      };
      
      //接下来定义继承基类的子类
      class fruit:public hotel{
      public:
          void order(){
              cout<<"吃水果"<<endl;
          }
      };
      class beef:public hotel{
      public:
          void order(){
              cout<<"吃牛肉"<<endl;
          }
      };
      class chicken:public hotel
      {
      public:
          void order(){
              cout<<"吃鸡肉"<<endl;
          }
      };
      
      //定义工厂基类
      class FactoryBase{
      public:
          virtual hotel* CreateHotel()=0;
      };
      
      //下面继承工厂基类,给每个子类独立出来一个工厂
      //这样就是独立的工厂产生方式
      class Fruit:public FactoryBase{
      public:
          hotel* CreateHotel(){
              return new fruit();
          }
      };
      class Beef:public FactoryBase
      {
      public:
          hotel* CreateHotel(){
              return new beef();
          }
      };
      class Chicken:public FactoryBase
      {
      public:
          hotel* CreateHotel(){
              return new chicken();
          }
      };
      
      int main() {
          Fruit ft;
          ft.CreateHotel()->order();
      
          Beef bf;
          bf.CreateHotel()->order();
      
          Chicken ch;
          ch.CreateHotel()->order();
      
          return 0;
      }
      
      

在这里插入图片描述

  • 和简单工厂进行比较

    • 工厂方法模式的应用并不仅仅是为了封装对象的创建,而是要把对象的创建放到同一个工厂子类中去实现,简单工厂则全部都是在同一个工厂之中进行创建
  • 工厂方法模式的组成

    • 抽象工厂角色:这是工厂模式的核心,与应用程序无关,是具体工厂角色必须实现的接口或必须继承的父类。比如上的FactoryBase
    • 具体工厂角色:它含有和具体业务逻辑有关的代码,由应用程序调用以创建对应的具体产品的对象。比如上述的ft,bf
    • 抽象产品角色:它是具体产品继承的父类或者是实现的接口。比如上述的hotel
    • 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。比如上述的fruit实例化对象
  • 缺点

    • 每增加一种产品就需要增加一个类,当产品非常多时,就需要增加非常多的类
  • 抽象工厂

    • 设定场景:假设这个饭店发现除了做饭,卖葡萄酒也是挺赚钱的,因此决定卖葡萄酒。饭菜和酒有价格档次的差别.比如产房A卖水果和白葡萄酒,产房B卖牛肉和红葡萄酒
    • 和工厂方法进行比较
      • 在创建对象的时候更加的复杂
      • 抽象工厂模式需要满足的条件
      • 系统中有多个同族的产品,而系统一次只可能消费其中一族产品
      • 同属同一个产品族的以其使用
    #include <iostream>
    using namespace  std;
    
    //定义一个抽象的基类
    class hotel{
    public:
        virtual ~hotel(){};
        virtual void order()=0;//点餐,是一个接口类
    };
    
    //接下来定义继承基类的子类
    class fruit:public hotel{
    public:
        void order(){
            cout<<"吃水果"<<endl;
        }
    };
    class beef:public hotel{
    public:
        void order(){
            cout<<"吃牛肉"<<endl;
        }
    };
    class chicken:public hotel
    {
    public:
        void order(){
            cout<<"吃鸡肉"<<endl;
        }
    };
    
    //定义葡萄酒基类
    class wine{
    public:
        ~wine(){};
        virtual void sold()=0;//葡萄酒售卖价格接口继承类
    };
    
    class WriteWine:public wine
    {
    public:
        void sold(){
            cout<<"白葡萄酒一百八一瓶"<<endl;
        }
    };
    class RedWine:public wine
    {
    public:
        void sold(){
            cout<<"红葡萄酒一万八一瓶"<<endl;
        }
    };
    
    
    
    class FactoryBase{
    public:
        virtual hotel* CreateHotel()=0;//菜肴工厂继承接口
        virtual wine* CreateWine()=0;//葡萄酒工厂继承接口
    };
    
    class FactoryA:public FactoryBase
    {
    public:
        hotel* CreateHotel(){
            return new fruit;
        }
        wine* CreateWine(){
            return new WriteWine();
        }
    
    };
    class FactoryB:public FactoryBase
    {
    public:
        hotel* CreateHotel(){
            return new beef;
        }
        wine* CreateWine(){
            return new RedWine();
        }
    };
    
    int main() {
        FactoryA a;
        a.CreateHotel()->order();
        a.CreateWine()->sold();
        FactoryB b;
        b.CreateHotel()->order();
        b.CreateWine()->sold();
    
        return 0;
    }
    
    

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值