1. 程式人生 > >設計模式C++實現——工廠方法模式

設計模式C++實現——工廠方法模式

對象 類型 begin 創建對象 dia rate rod rtu log

模式定義:

工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。

工廠方法讓類把實例化推遲到子類。

模式結構:

技術分享

Creator是一個類,它實現了全部操縱產品的方法,但不實現工廠方法。

Creator的全部子類都必須實現工廠方法(factoryMethod()),以實際制造出產品。

全部的產品必須實現Product基類。這樣一來使用這些產品的類就能夠引用這個基類,而不是派生類。

舉例:

披薩店希望可以開一些加盟店。

經營者希望確保加盟店運營的質量,所以希望這些店都使用能經過實踐考研的代碼。問題在於每家加盟店都可能想要提供不同風味的披薩(例如說紐約。芝加哥,加州)。這收到了開店地點及該地區披薩口味的影響。

解決的方法:讓每一個區域風味的披薩工廠繼承基類披薩工廠使披薩工廠的訂單系統不變。然後創建自己風味的披薩。這樣真正選購披薩類型,使用詳細的披薩工廠決定的。

類圖設計:

技術分享

編程實現及運行結果:

#include <iostream>
#include <string>
#include <list>
using namespace std;


首先創建Pizza類

class Pizza
{
public:
	Pizza(string nam, string doug, string sauc)
	{
		name = nam;
		dough = doug;
		sauce = sauc;
	}
	void addTops(string tops)
	{
		toppings.push_back(tops);
	}

	void prepare()
	{
		cout << "Preparing " << name << endl;
		cout << "Tossing dough" << endl;
		cout << "Adding sauce" << endl;
		cout << "Adding toppings" << endl;
		list<string>::iterator iter = toppings.begin();
		for(; iter!=toppings.end(); ++iter)
		{
			cout << "	"<< *iter;
		}
		cout << endl;
	}

	void bake()
	{
		cout << "Bake for 25 minutes at 350" << endl;
	}

	void cut()
	{
		cout << "Cutting the pizza into diagonal slices" << endl;
	}

	void box()
	{
		cout << "Place pizza in offical PizzaStore box" << endl;
	}

	string getName()
	{
		return name;
	}

private:
	string name;
	string dough;
	string sauce;
	list<string> toppings;
};


然後創建紐約cheese風格的pizza類和紐約clam風格的pizza類

class NYStyleCheesePizza : public Pizza
{
public:
	NYStyleCheesePizza():Pizza("NY Style Sauce and Cheese Pizza", 
		"Thin Crust Dough", "Marinara Sauce")
	{
		addTops("Grated Reggiano Cheese");
	}
};
class NYStyleClamPizza : public Pizza
{
public:
	NYStyleClamPizza():Pizza("NY Style Sauce and Clam Pizza", 
		"Thin Crust Dough", "Marinara Sauce")
	{
		addTops("Grated Clam");
	}
};

創建基類工廠

class PizzaStore
{
public:
	virtual ~PizzaStore(){}

	Pizza* oderPizza(string type)
	{
		Pizza* pizza = createPizza(type);
		pizza->prepare();
		pizza->bake();
		pizza->cut();
		pizza->box();

		return pizza;
	}

	virtual Pizza* createPizza(string type){return NULL;}
	
};


創建詳細類工廠(紐約pizza工廠)

class NYPizzaStore : public PizzaStore
{
public:
	Pizza* createPizza(string item)
	{
		if(item == "cheese")
		{
			return new NYStyleCheesePizza();
		}
		else if(item == "clam")
		{
			return new NYStyleClamPizza();
		}
		else 
			return NULL;
	}
};
//...創建其它地區工廠...

客戶代碼:

int main()
{
	PizzaStore* nyStore = new NYPizzaStore();
	Pizza* pizza = nyStore->oderPizza("cheese");
	cout << "Ethan ordered a "<< pizza->getName() << endl;

	return 0;
}

運行結果:

PreparingNY Style Sauce and Cheese Pizza

Tossingdough

Addingsauce

Addingtoppings

Grated Reggiano Cheese

Bakefor 25 minutes at 350

Cuttingthe pizza into diagonal slices

Placepizza in offical PizzaStore box

Ethanordered a NY Style Sauce and Cheese Pizza

請按隨意鍵繼續. . .

設計原則的應用:

設計原則6:依賴倒置原則(Dependency Inversion Priciple):要依賴抽象,不要依賴詳細類。

設計原則4:工廠方法用來處理對象的創建,並將這種行為封裝在子類中。這樣,客戶中關於基類的代碼和子類對象對象創建代碼解耦了。


參考Head First設計模式

設計模式C++實現——工廠方法模式