模式定义:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。
工厂方法让类把实例化推迟到子类。
模式结构:
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设计模式