设计模式

工厂模式属于创建型模式,主要分为:简单工厂模式,工厂方法模式,抽象工厂模式

简单工厂模式

主要特点就是需要在工厂类中做判断,从而创造相应的产品,当增加新的产品时,需要修改工厂类。举例,有家生产处理器核的厂家,仅有一家工厂,能生产两种型号的处理器,客户需要什么样的处理器,一定要显式地告诉工厂生产。

例:

 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 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 
18 //多核 
19 class MultiCore {
20     public:
21     virtual void show() = 0;
22 };
23 
24 class MultiCoreA: public MultiCore {
25     public:
26     void show() { cout << "MultiCore A" << endl; }
27 };
28 
29 class MultiCoreB: public MultiCore {
30     public:
31     void show() { cout << "MultiCore B" << endl; }
32 };
33 
34 //工厂  
35 class Factory {
36     public:
37     virtual SingleCore* createSingleCore() = 0;
38     virtual MultiCore* createMultliCore() = 0;
39 };
40 
41 //工厂A,专门用来生产A型号的处理器 
42 class FactoryA :public Factory{
43     public:
44     SingleCore* createSingleCore() {return new SingleCoreA();}
45     MultiCore* createMultiCore() { return new MultiCoreA(); }
46 };
47 
48 //工厂B,专门用来生产B型号的处理器  
49 class FactoryB :public Factory{
50     public:
51     SingleCore* createSingleCore() {return new SingleCoreB();}
52     MultiCore* createMultiCore() { return new MultiCoreB(); }
53 
54 };

动机

  • 在软件系统中,经常面临着“一系列相互依赖的对象工作”;同时,由于需求的变化,往往存在更多系列对象的创建工作。
  • 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合。

模式定义

  • 提供一个接口,让该接口负责创建一系列”相关或者相互依赖的对象“,无需指定它们具体的类。 ——《设计模式》GoF

要点总结

  • 如果没有应对”多系列对象创建“的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂即可。
  • ”系列对象“指的是在某一个特定系列的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。
  • Abstract Factory模式主要在于应用”新系列“的需求变动。其缺点在与难以应对”新对象“的需求变动。
原文地址:https://www.cnblogs.com/y4247464/p/14261680.html