## 模式定义:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
## 模式结构:
![](https://box.kancloud.cn/2016-08-30_57c5458e6ea3f.jpg)
Creator是一个类,它实现了所有操纵产品的方法,但不实现工厂方法。Creator的所有子类都必须实现工厂方法(factoryMethod()),以实际制造出产品。
所有的产品必须实现Product基类,这样一来使用这些产品的类就可以引用这个基类,而不是派生类。
## 举例:
披萨店希望能够开一些加盟店。经营者希望确保加盟店运营的质量,所以希望这些店都使用能经过实践考研的代码。问题在于每家加盟店都可能想要提供不同风味的披萨(比方说纽约,芝加哥,加州),这收到了开店地点及该地区披萨口味的影响。
解决办法:让每个区域风味的披萨工厂继承基类披萨工厂使披萨工厂的订单系统不变,然后创建自己风味的披萨。这样真正选购披萨类型,使用具体的披萨工厂决定的。
## 类图设计:
![](https://box.kancloud.cn/2016-08-30_57c5458e9ed77.jpg)
## 编程实现及执行结果:
~~~
#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设计模式