標籤:c style class blog code a
模式定義:
Factory 方法模式定義了一個建立對象的介面,但由子類決定要執行個體化的類是哪一個。Factory 方法讓類把執行個體化延遲到子類。
模式結構:
Creator是一個類,它實現了所有操縱產品的方法,但不實現Factory 方法。Creator的所有子類都必須實現Factory 方法(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:Factory 方法用來處理對象的建立,並將這樣的行為封裝在子類中。這樣,客戶中關於基類的代碼和子類對象對象建立代碼解耦了。
參考Head First設計模式