1. 程式人生 > >設計模式入門學習 工廠模式

設計模式入門學習 工廠模式

  先讀一本設計模式入門書,深入淺出設計模式,之後再拜讀一下GOF設計模式。

  工作也有兩年時間了,說設計模式接觸的應該比較多了,只是一直沒有進行系統的整理。說起來,剛入職做Webkit這讓我有一個比較高的技術起點,技術視界也比較寬廣。抓時間系統過一遍設計模式,探究下編碼的藝術。

  工廠模式:為建立物件提供過渡介面,以便將建立物件的具體過程遮蔽隔離起來。好比是:工廠生產產品,只需要告訴工廠需要什麼樣的產品,不需關心製造產品的具體過程。

  書中將工廠模式分為三類:

  簡單工廠模式

  工廠方法模式

  抽象工廠模式

1. 簡單工廠模式

  和名字一樣很簡單,由如下組成:

  1. 工廠      建立“產品”物件統一通過“工廠”進行,只需要告訴工廠不同的產品需求,就會產生具體產品。不需要了解產品製造過程。

  2. 抽象的產品   具體產品的父類,定義同類產品的通用特性。

  3. 具體的產品   就是具體的產品

  直接上程式碼,對程式設計師來說,這是最直觀的解釋。

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;
			}
		}
	};
  這種模式,並不符合開閉原則,如果新增汽車型別,那麼需要修改CarFactory中靜態函式的switch程式碼。

2. 工廠方法模式

  工廠方法模式去掉簡單工廠模式中,工廠方法的靜態屬性,使可以被子類繼承。它的組成如下:

  1. 抽象工廠

  2. 具體工廠

  3. 抽象產品

  4. 具體產品

  抽象產品和具體產品的程式碼不需要修改,下面沒有列出,以下是抽象工廠和具體工廠的實現。

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();
  可以看到,由於加入抽象工廠,物件的數量成倍增長,每個產品都需要對應一個工廠。當然,我們可以通過傳入atype引數,將一類汽車放入一個工廠中生產。

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();