設計模式入門學習 工廠模式
阿新 • • 發佈:2019-01-03
先讀一本設計模式入門書,深入淺出設計模式,之後再拜讀一下GOF設計模式。
工作也有兩年時間了,說設計模式接觸的應該比較多了,只是一直沒有進行系統的整理。說起來,剛入職做Webkit這讓我有一個比較高的技術起點,技術視界也比較寬廣。抓時間系統過一遍設計模式,探究下編碼的藝術。
工廠模式:為建立物件提供過渡介面,以便將建立物件的具體過程遮蔽隔離起來。好比是:工廠生產產品,只需要告訴工廠需要什麼樣的產品,不需關心製造產品的具體過程。
書中將工廠模式分為三類:
簡單工廠模式
工廠方法模式
抽象工廠模式
1. 簡單工廠模式
和名字一樣很簡單,由如下組成:
1. 工廠 建立“產品”物件統一通過“工廠”進行,只需要告訴工廠不同的產品需求,就會產生具體產品。不需要了解產品製造過程。
2. 抽象的產品 具體產品的父類,定義同類產品的通用特性。
3. 具體的產品 就是具體的產品
直接上程式碼,對程式設計師來說,這是最直觀的解釋。
這種模式,並不符合開閉原則,如果新增汽車型別,那麼需要修改CarFactory中靜態函式的switch程式碼。enum TCarType { EBenz, EBMW }; //抽象產品 class Car { public: virtual void Drive() = NULL; }; //具體產品 class Benz : public Car { public: void Drive(){ /*benz drive method*/ } }; class BMW : public Car { public: void Drive(){ /*BMW drive method*/ } }; class CarFactory { public: static Car* ProduceCar(TCarType atype) { switch (atype) { case EBenz : return new Benz(); case EBMW : return new BMW(); default : return NULL; } } };
2. 工廠方法模式
工廠方法模式去掉簡單工廠模式中,工廠方法的靜態屬性,使可以被子類繼承。它的組成如下:
1. 抽象工廠
2. 具體工廠
3. 抽象產品
4. 具體產品
抽象產品和具體產品的程式碼不需要修改,下面沒有列出,以下是抽象工廠和具體工廠的實現。
可以看到,由於加入抽象工廠,物件的數量成倍增長,每個產品都需要對應一個工廠。當然,我們可以通過傳入atype引數,將一類汽車放入一個工廠中生產。class CarFactory { public: virtual Car* ProduceCar(/*TCarType atype*/) = NULL; }; class BenzFactory { public: Car* ProduceCar(/*TCarType atype*/) { return new Benz(); } }; class BMWFactory { public: Car* ProduceCar(/*TCarType atype*/) { return new BMW(); } }; //簡單呼叫方法 CarFactory* facory = new BMWFactory(); Car* bmw = facory->ProduceCar();
3. 抽象工廠模式
我覺得這個和工廠方法模式區別不大,就是對工廠和產品做了一個分類。
//抽象產品
class NewCar
{
public:
virtual void DriveNew() = NULL;
};
class OldCar
{
public:
virtual void DriveOld() = NULL;
};
//具體產品
class BenzNew : public NewCar
{
public:
void Drive(){ /*benz drive method*/ }
};
class BenzOld : public OldCar
{
public:
void Drive(){ /*benz drive method*/ }
};
class BMWNew : public NewCar
{
public:
void Drive(){ /*BMW drive method*/ }
};
class BMWOld : public OldCar
{
public:
void Drive(){ /*BMW drive method*/ }
};
//工廠
class CarFactory
{
public:
virtual NewCar* ProduceNewCar(/*TCarType atype*/) = NULL;
virtual OldCar* ProduceOldCar(/*TCarType atype*/) = NULL;
};
class BenzFactory : public CarFactory
{
public:
NewCar* ProduceNewCar(/*TCarType atype*/)
{
return new BenzNew();
}
OldCar* ProduceOldCar(/*TCarType atype*/)
{
return new BenzOld();
}
};
class BMWFactory : public CarFactory
{
public:
NewCar* ProduceNewCar(/*TCarType atype*/)
{
return new BMWNew();
}
OldCar* ProduceOldCar(/*TCarType atype*/)
{
return new BMWOld();
}
};
//簡單呼叫方法
CarFactory* factory = new BenzFactory();
NewCar* newCar = factory->ProduceNewCar();
OldCar* oldCar = factory->ProduceOldCar();