簡介
用一個單獨的類來做創建實例的過程,是工廠;用工廠方法代替new操作的一種模式;工廠模式就相當於創建實例對象的new,我們經常要根據類Class生成實例對象。
分類
簡單工廠模式、工廠方法模式、抽象工廠模式
爲什麼要使用工廠模式?
- 程序更規範有條理,當我們創建實例對象時,如果不僅僅做賦值這樣簡單的事情,而是有一大段邏輯,那這個時候我們要將所有的初始化邏輯都寫在構造函數中嗎? 顯然,這樣使得代碼很難看;
- 降低耦合度,提高可閱讀性。面向對象的基本思想封裝告訴我們,我們儘量將長的代碼進行"切割",再將每一個小邏輯都"封裝"起來,這樣可以降低耦合度,修改的時候也可以直奔錯誤段落。
1)簡單工廠模式
簡介
簡單工廠模式是屬於創建型模式,又叫做靜態工廠方法(static Factory Method)模式,簡單工廠模式是由一個工廠對象決定創建出來哪一種產品類的實例。
特點
是由一個工廠類根據傳入的參數,動態決定應該創建哪一類產品類(這些產品類繼承自一個父類或接口)的實例;
需要在工廠類中作出判斷,在創建產品的時候,指定響應產品創造。
舉個例子:
假設有一個工廠,他能生產出A、B兩種產品。當客戶需要產品的時候一定要告訴共產是哪種產品,是A還是B。當新增加一種新產品的時候,那麼就要去修改工廠的類。
應用說明:
一個工廠,多個產品。產品需要有一個虛基類。通過傳入參數,生成具體產品對象,並利用基類指針指向此對象。
程序案例:
#include "stdafx.h"
#include <iostream>
using namespace std;
//類方法—生產的產品
class Product
{
public:
virtual void show()=0;
}
class Product_A :public Product //產品A
{
public:
void show()
{
cout<<"Product_A"<<endl;
}
};
class Product_B : public Product //產品B
{
public:
void show()
{
cout<<"Product_B"<<endl;
}
};
//工廠
class Factory //只有一家工廠,可以生產不同的產品
{
public:
Product* Create(int i)
{
switch(i)
{
case 1: //生產產品A
return new Prodent_A;
break;
case 2: //生產產品B
return new Product_B;
break;
default:
break;
}
}
};
int main()
{
Factory *factoty = new Factory(); //實例化--工廠對象
factoty->Create(1)->show(); //指定生產A產品
factoty->Create(2)->show(); //指定生產B產品
system("pause");
return 0;
}
缺點:
每次新增一個類時,都需要改變工廠函數,破壞了封裝性;(如果生產廠家需要新增一個產品,那麼工廠函數Factory就需要跟着改變,所以上面的工廠模式違背了開放封閉原則;)
補:開放封閉原則:軟件實體(類、模塊、函數)可以擴展,但是不可修改。
2)工廠方法模式
簡介
多個工廠,多個產品,每個產品對應於一個工廠。此時工廠和產品都是通過虛基類的方式構建。
特點
定義一個用於創建對象的接口,讓子類決定實例化哪一個類。
當增加一個新產品時,同時增加一個新工廠。增加新工廠屬於擴展,不會修改以前工廠類和產品類的任何代碼。可以看過多個獨立的簡單工廠模式構成了工廠方法模式。
舉個例子:
假設現在有A、B兩種產品,那麼久開兩個工廠。工廠A負責生產A產品,工廠B負責生產B種產品。這時候客戶不需要告訴共產生產哪種產品了,只需要告訴共產生產就可以了。
應用說明:
把簡單工廠模式中的工廠類抽象出一個接口,這個接口只有一個方法,就是創建抽象產品的工廠方法。
程序案例:
#include "stdafx.h"
#include<iostream>
using namespace std;
//類方法—生產的產品
class Product
{
public:
virtual void show() = 0;
};
class Product_A : public Product //產品A
{
public:
void show()
{
cout << "Product_A" << endl;
}
};
class Product_B : public Product //產品B
{
public:
void show()
{
cout << "Product_B" << endl;
}
};
class Factory //工廠
{
public:
virtual Product* create() = 0;
};
class Factory_A : public Factory //工廠A 只有一個函數方法(產品)
{
public:
Product* create()
{
return new Product_A;
}
};
class Factory_B : public Factory //工廠B 只有一個函數方法(產品)
{
public:
Product* create()
{
return new Product_B;
}
};
int main()
{
Factory_A* productA = new Factory_A(); //實例化--工廠對象A
Factory_B* productB = new Factory_B(); //實例化--工廠對象B
productA->create()->show(); //工廠A 調用函數(生產產品)
productB->create()->show(); //工廠B 調用函數(生產產品)
system("pause");
return 0;
}
缺點:
每增加一個新的產品,就需要增加一個新的工廠
3)抽象工廠模式
簡介
多個工廠,多個產品,並且每個產品可以包含多個型號。此時工廠和產品都是通過虛基類的方式構建。每一個工廠類可以生產同一個產品的多個型號。
特點
提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
舉個例子:
例1)假如我們A產品中有A1和A2兩種型號的廠品,B產品中有B1和B2兩種型號的廠品,那怎麼辦,上面兩種工廠模式就不能解決了。這個時候抽象工廠模式就登場了。還是開設兩家工廠,工廠A負責生產A1 、A2型號產品,B工廠負責生產B1、B2型號的產品。
例2)假設一種情況,在的家中,某一個衣櫃(具體工廠)只能存放某一種這樣的衣服(成套,一系列具體產品),每次拿這種成套的衣服時也自然要從這個衣櫃中取出了。用 OOP 的思想去理解,所有的衣櫃(具體工廠)都是衣櫃類的(抽象工廠)某一個,而每一件成套的衣服又包括具體的上衣(某一具體產品),褲子(某一具體產品),這些具體的上衣其實也都是上衣(抽象產品),具體的褲子也都是褲子(另一個抽象產品)。
優點:當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。
缺點:產品族擴展非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 里加代碼,又要在具體的裏面加代碼。
應用說明:
#include <iostream>
using namespace std;
//定義抽象類
class product1
{
public:
virtual void show() = 0;
};
//定義具體類
class product_A1 :public product1
{
public:
void show(){ cout << "product A1" << endl; }
};
class product_B1 :public product1
{
public:
void show(){ cout << "product B1" << endl; }
};
//定義抽象類
class product2
{
public:
virtual void show() = 0;
};
//定義具體類
class product_A2 :public product2
{
public:
void show(){ cout << "product A2" << endl; }
};
class product_B2 :public product2
{
public:
void show(){ cout << "product B2" << endl; }
};
class Factory //工廠
{
public:
virtual product1 *creat1() = 0;
virtual product2 *creat2() = 0;
};
class FactoryA //工廠A 可以有多個函數方法(產品)
{
public:
product1 *creat1(){ return new product_A1(); }
product2 *creat2(){ return new product_A2(); }
};
class FactoryB //工廠B 可以有多個函數方法(產品)
{
public:
product1 *creat1(){ return new product_B1(); }
product2 *creat2(){ return new product_B2(); }
};
int main()
{
FactoryA *factoryA = new FactoryA(); //實例化--工廠對象A
factoryA->creat1()->show(); //工廠A 調用函數(生產產品1)
factoryA->creat2()->show(); //工廠A 調用函數(生產產品2)
FactoryB *factoryB = new FactoryB(); //實例化--工廠對象B
factoryB->creat1()->show(); //工廠B 調用函數(生產產品1)
factoryB->creat2()->show(); //工廠B 調用函數(生產產品2)
return 0;
}
優點:
易於交換產品系列,由於具體工廠類在一個應用中只需要在初始化的時候出現一次,這樣就使得改變一個應用的具體工廠變得非常容易,只需要改變具體工廠即可使用不同的產品配置。
讓具體的創建實例過程與客戶端分離,客戶端是通過它們的抽象接口操縱實例,產品的具體類名也被具體工廠實現分離,不會出現在客戶代碼中。
缺點:
增加新的產品時需要改動多處代碼。
希望你對有幫助;
如發現有錯誤的,歡迎指正。