设计模式 - Factory 工厂模式
工厂模式属于创建型模式,主要分为:简单工厂模式,工厂方法模式,抽象工厂模式
简单工厂模式
主要特点就是需要在工厂类中做判断,从而创造相应的产品,当增加新的产品时,需要修改工厂类。举例,有家生产处理器核的厂家,仅有一家工厂,能生产两种型号的处理器,客户需要什么样的处理器,一定要显式地告诉工厂生产。
例:
1 enum CTYPE {COREA, COREB}; 2 3 class SingleCore { 4 public: 5 virtual void show() = 0; 6 }; 7 8 //单核A 9 class SingleCoreA: public SingleCore { 10 public: 11 void show() { cout << "SingleCore A" << endl; } 12 }; 13 //单核B 14 class SingleCoreB: public SingleCore { 15 public: 16 void show() { cout << "SingleCore B" << endl; } 17 }; 18 19 //唯一的工厂,可以生产两种型号的处理器核,在内部判断 20 class Factory { 21 public: 22 SingleCore* createSingleCore(enum CTYPE core) { 23 if(core == COREA) { 24 return new SingleCoreA(); 25 }else if(core == COREB) { 26 return new SingleCoreB(); 27 }else 28 return nullptr; 29 } 30 };
缺点:
如果增加新的处理器核类型,只能通过修改工厂类代码增加处理器的类型,这就违反了开闭原则:对扩展开放,对更改封闭。
因此工厂方法模式出现了,即定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。
Factory Method
接着举例:这家生产处理器核的厂家赚到飞天,就决定再开设一个工厂专门生产B型号的单核,而原来的工厂专门原来生产A单核。如此,客户有需求就直接找生产对应核的工厂就可以,无须告诉工厂需要什么样的核。
例子:
1 class SingleCore { 2 public: 3 virtual void show() = 0; 4 }; 5 6 //单核A 7 class SingleCoreA: public SingleCore { 8 public: 9 void show() { cout << "SingleCore A" << endl; } 10 }; 11 //单核B 12 class SingleCoreB: public SingleCore { 13 public: 14 void show() { cout << "SingleCore B" << endl; } 15 }; 16 17 class Factory { 18 public: 19 virtual SingleCore* createSingleCore() = 0; 20 }; 21 //生产A核的工厂 22 class FactoryA :public Factory{ 23 public: 24 SingleCoreA* createSingleCore() {return new SingleCoreA();} 25 }; 26 27 //生产B核的工厂 28 class FactoryB :public Factory{ 29 public: 30 SingleCoreB* createSingleCore() {return new SingleCoreB();} 31 };
当然,工厂方法模式也有缺点,新的工厂会随着新产品的增加而增加,会需要很多的类定义。
动机
- 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
- 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
模式定义
- 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。 ——《设计模式》GoF
要点总结
- Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
- Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
- Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。
Abstract Factory
随着这家公司技术不断进步,可以生产多核处理器了,抽象工厂模式中,提供一个创建一系列相关或依赖对象的接口,而无须为相关联的不同产品分别指定具体的类。同样,该厂家开设两家工厂,一个专门生产A型号的单核与多核处理器,另一个专门生产B型号的单核与多核处理器。实现如下:
1 #include <iostream> 2 3 using namespace std; 4 5 class SingleCore { 6 public: 7 virtual void show() = 0; 8 }; 9 10 //单核A 11 class SingleCoreA : public SingleCore { 12 public: 13 void show() { cout << "SingleCore A" << endl; } 14 }; 15 //单核B 16 class SingleCoreB : public SingleCore { 17 public: 18 void show() { cout << "SingleCore B" << endl; } 19 }; 20 21 //多核 22 class MultiCore { 23 public: 24 virtual void show() = 0; 25 }; 26 27 class MultiCoreA : public MultiCore { 28 public: 29 void show() { cout << "MultiCore A" << endl; } 30 }; 31 32 class MultiCoreB : public MultiCore { 33 public: 34 void show() { cout << "MultiCore B" << endl; } 35 }; 36 37 //工厂 38 class Factory { 39 public: 40 virtual SingleCore* createSingleCore() = 0; 41 virtual MultiCore* createMultiCore() = 0; 42 }; 43 44 //工厂A,专门用来生产A型号的处理器 45 class FactoryA : public Factory { 46 public: 47 SingleCoreA* createSingleCore() { return new SingleCoreA; } 48 MultiCoreA* createMultiCore() { return new MultiCoreA; } 49 }; 50 51 //工厂B,专门用来生产B型号的处理器 52 class FactoryB : public Factory { 53 public: 54 SingleCoreB* createSingleCore() { return new SingleCoreB(); } 55 MultiCoreB* createMultiCore() { return new MultiCoreB(); } 56 }; 57 58 int main() { 59 FactoryA* factoryA = new FactoryA(); 60 FactoryB* factoryB = new FactoryB(); 61 factoryA->createSingleCore()->show(); 62 factoryA->createMultiCore()->show(); 63 factoryB->createSingleCore()->show(); 64 factoryB->createMultiCore()->show(); 65 return 0; 66 }
动机
- 在软件系统中,经常面临着“一系列相互依赖的对象工作”;同时,由于需求的变化,往往存在更多系列对象的创建工作。
- 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合。
模式定义
- 提供一个接口,让该接口负责创建一系列”相关或者相互依赖的对象“,无需指定它们具体的类。 ——《设计模式》GoF
要点总结
- 如果没有应对”多系列对象创建“的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂即可。
- ”系列对象“指的是在某一个特定系列的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
- Abstract Factory模式主要在于应用”新系列“的需求变动。其缺点在与难以应对”新对象“的需求变动。