三种工厂模式详解

 

我的相关博文:

别只知道策略模式+简单工厂,试试更香的策略模式+抽象工厂!

 

1. 简单工厂模式, 一图就看尽

    涉及: 产品抽象类(即水果类)  、 工厂类、具体产品类(香蕉类、苹果类)

 

 

 

2.

工厂方法模式使用先来看一下,上截图:

 

 工厂方法模式的实现:

 3             class SingleCore  // 抽象类,抽象的处理器类。 具体产品的基类 
 4             {
 5             public:
 6                 virtual void Show() = 0;
 7             };
 8             class SingleCoreA:public SingleCore // 具体型号的处理器A 具体的产品类
 9             {
10             public:
11                 void Show()
12                 {
13                     cout << "单核处理器 A型" << endl;
14                 }
15             };
16             class SingleCoreB:public SingleCore // 具体型号的处理器B 具体的产品类
17             {
18             public:
19                 void Show()
20                 {
21                     cout << "单核处理器 B型" << endl;
22                 }
23             };
24             class Factory   // 抽象类, 工厂类  具体工厂的基类
25             {
26             public:
27                 virtual SingleCore* CreateSingleCore() = 0;
28             };
29             class FactoryA:public Factory // 具体的工厂类 厂子1
30             {
31             public:
32                 SingleCore* CreateSingleCore()
33                 {
34                     cout << "Create SingleCore A" << endl;
35                     return new SingleCoreA(); // 厂子1生产A型CPU
36                 }
37             };
38             class FactoryB:public Factory // 具体的工厂类 厂子2
39             {
40             public:
41                 SingleCore* CreateSingleCore()
42                 {
43                     cout << "Create SingleCore B" << endl;
44                     return new SingleCoreB(); //厂子2生产B型CPU
45                 }
46             };

  

小结:

前者是简单工厂模式、后者是工厂方法模式。 

简单工厂=》优点:使用简单。缺点:父类决定实例化哪个类, 在工厂内部直接创建产品,导致新增产品时就需要去修改工厂类的内部代码。  

工厂方法=》优点:让子类决定实例化哪个类,将创建过程延迟到子类进行。   缺点:每增加一个新产品,就需要增加一个新产品的工厂。

个人见解:

感悟1.

工厂方法类的核心是一个抽象的工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式,是因为具体工厂类都有共同的抽象父类。

感悟2.

纵观本例需要实现的功能:吃苹果、吃香蕉,吃是动词。苹果或香蕉是名词,

显然,如果我们能封装出一个吃函数,其参数是具体水果的标识(或称为ID,标识具体水果品种),那么用户使用时候会更加方便。

从本例子来看,简单工厂模式在使用的时候可以传入特定字符串,显然是简单工厂模式更加容易封装出符合此要求的函数,而工厂方法模式则不太容易满足此要求。 

最后,我的态度是设计模式没有好坏,只有根据当前场景、程序员的需求,进行特定的挑选和使用。

 

 

 3.抽象工厂模式

抽象工厂模式是一个创建型设计模式,它针对的是创建产品族,而不是单单一个产品。

说大白话,上面的工厂方法模式的示例代码,只维护了一个SingleCore类,也就是只有一个产品线。

如果是维护多个产品线的情况,例如有生产CPU,还有生产水果,还有输出语音控制(每种语音可视为一种产品,其抽象类则是获取对应的语音ID)等,

那么抽象的工厂类里就需要声明多个纯虚函数。

经过这样的简单修改,就可以创建产品族,这就成了抽象工厂模式了。所以,抽象工厂和工厂方法其实是极其类似的。

#include <iostream>
#include <string>
 
using namespace std;
 
// 点评shape类: 一条产品线下的产品,通常存在共性,也就是说,一个产品抽象类通常是需要的,而不是必须的。   
class Shape
{
public:
    virtual void draw()=0;
    virtual ~Shape(){}
};
 
class Rectangle :public Shape
{
public:
    void draw()
    {
        cout << "from rectangle"<<endl;
    }
};
 
class Circle :public Shape
{
public:
    void draw()
    {
        cout << "from circle"<< endl;
    }
};

// 点评color类: 一条产品线下的产品,通常存在共性,也就是说,一个产品抽象类通常是需要的,而不是必须的。    class Color { public: virtual void fill()=0; virtual ~Color(){} }; class Green:public Color { public: void fill() { cout << "color green"<<endl; } }; class Red:public Color { public: void fill() { cout << "color red"<<endl; } }; class AbFactory // 抽象工厂这里可以实现多个纯虚方法 { public: virtual Shape* createShape(string Shape)=0; virtual Color* fillColor(string color)=0; virtual ~AbFactory(){} }; class ShapeFactory:public AbFactory { public: Color* fillColor(string color) { return NULL; } Shape* createShape(string shape) { if(shape=="rectangle"){ return new Rectangle(); } else if(shape == "circle") { return new Circle(); } return NULL; } }; class ColorFactory:public AbFactory { public: Color* fillColor(string color) { if(color=="green"){ return new Green(); } else if(color == "red") { return new Red(); } return NULL; } Shape* createShape(string shape) { return NULL; } }; int main(int argc, char *argv[]) { AbFactory* abfactory; // 创建抽象工厂指针 abfactory = new ShapeFactory(); // 创建绘图工厂 Shape* shape = abfactory->createShape("rectangle"); //获取绘制矩形的工具(产品) if(shape == NULL) { cout << "shape is NULL"; } else { shape->draw(); // 使用绘制矩形的产品 } delete shape; delete abfactory; abfactory = new ColorFactory(); // 创建喷漆工厂 Color* color = abfactory->fillColor("red"); //获取喷红漆的工具(产品) if(color == NULL) { cout << "color is NULL"; } else { color->fill(); // 使用喷红漆的产品 } delete color; delete abfactory; return 0; }

 

个人理解:   

0. 封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。这点是明显区分于简单工厂的。

1.抽象工厂类似总公司,负责规定并建立所有的产品线(即声明纯虚函数),原则上以后不允许再新增产品线,否则需要在该类内部新增纯虚函数,这破坏了开闭原则。   

2.继承于抽象工厂类的具体工厂,根据需要可以选择性(部分或全部)实现产品线(即上述纯虚函数)来创建具体的产品。这是符合开闭原则的,因为此时新增工厂,并不需要修改已有的代码。   

3. 创建一个具体产品的产品抽象类,具体产品类负责实现该产品抽象类。 

抽象工厂模式可以创建产品组,即:不同子公司(具体工厂类)都严格按照产品线来生产产品,然而各自产品线的具体产品可以个性化实现,  同时,一条产品线下的产品,通常存在共性,也就是说,一个产品抽象类通常是需要的,而不是必须的。   

小结: 抽象工厂模式,可以新增工厂(例如ColorFactory类),也可以新增具体产品(例如Rectangle类),但是不建议新增产品线,这会破坏开闭原则,

同时,产品抽象类的功能概念是与产品线的功能概念遥相呼应的存在,虽不是必须的,但通常是需要的。

 

 

文末:

抽象工厂,也可以参考 https://blog.csdn.net/konglongdanfo1/article/details/83380770   文章嘛 多看点好,不同的角度。

 

 

 

.

posted @ 2020-09-09 22:26  一匹夫  阅读(1392)  评论(0编辑  收藏  举报