一、是什么
- 工厂模式解决的主要问题是,将原来分布在各个地方的对象创建的过程单独抽离出来,交付给工厂来处理,其它地方想要使用直接调用工厂方法获取对象即可
- 我们可以抽象出一些类的公共接口来形成抽象父类或者接口,这样就可以通过声明一个指向父类的指针,来指向子类的实际实现,达到多态的目的
二、优缺点
- 优点
- 定义创建对象的接口,封装了对象创建的过程
- 使具体化类的工作延迟到了子类之中
- 缺点
- 程序员必须知道子类的名字,当子类非常多的时候命名是一件非常麻烦的事情
- 在父类之中并不知道具体要实例化哪一个具体的子类
三、工厂模式的分类和介绍
-
工厂模式主要分为以下三类
-
简单工厂
-
设定场景:去饭店点菜,有各种菜肴,需要给这个饭店建模
#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; }