我的相關博文:
別只知道策略模式+簡單工廠,試試更香的策略模式+抽象工廠!
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 文章嘛 多看點好,不同的角度。
.