您的位置:首页 > 编程语言 > C语言/C++

Head First设计模式C++实现--第四章:工厂(Factory)模式

2014-06-26 23:16 375 查看

工厂(Factory)模式

一、问题的提出

我们应该针对接口而不是实现编程,但是每次我们“new”一个对象的时候,我们不正是在进行针对实现编程吗?当有一群相关的具体类时,通常会写出这样的代码:
Duck* duck=NULL;
if(picnic)
{
duck = new MallardDuck();
}
else if
{
duck = new DecoyDuck();
}
else if
{
duck = new RubberDuck();
}
但是一旦有变化或扩展,就必须重新打开这段代码进行检查和修改。代码并非“对修改关闭”。
举例:根据类型订比萨
Pizza* orderPizza(string type)
{
Pizza* pizza=NULL;
if(type == "cheese")
{
pizza = new CheesePizza();
}
else if(type == "greek")
{
pizza = new GreekPizza();
}
else if(type == "pepperoni")
{
pizza = new PepperoniPizza();
}
}
当需要更多的比萨类型时orderPizza需要进行改动。
现在最好将创建对象的代码移动到orderPizza之外,把创建对象的代码搬到另一个对象中,这个新对象只管如何创建比萨,这个对象就是工厂,它的目的就是产生对象。

二、工厂方法模式

用一个实际的例子进行说明。
#ifndef FACTORY__H
#define FACTORY__H
#include <string>
#include <vector>
#include <iostream>
using namespace std;

class Pizza
{
public:
	string name;
	string dough;//面团
	string sauce;//浆料

	vector<string> toppings;

public:
	virtual void  prepare();
	virtual void bake();//烘烤
	virtual void cut();//切片
	virtual void box();//装箱
	virtual string getName();
};

//纽约Pizza
class NYStyleCheesePizza : public Pizza
{
public:
	NYStyleCheesePizza();
};

//芝加哥Pizza
class  ChicagoStylePizza : public Pizza
{
public:
	ChicagoStylePizza();
	void cut();
};

//比萨工厂(产生比萨对象)
class PizzaStore
{
public:
	Pizza* pizza;

	Pizza* orderPizza(string type);
	virtual Pizza* createPizza(string type) = 0;//每个子类必须重写此方法,达到<span style="color:#ff0000;">子类决定产生什么类型的对象</span>
};

//工厂类具体对象
class NYPizzaStore : public PizzaStore
{
public:
	Pizza* createPizza(string type);
};

#endif


cpp:
#include "Factory.h"

void Pizza::prepare()
{
	cout<<"Preparing "<<name<<endl;
	cout<<"Tossing dough..."<<endl;
	cout<<"Adding sauce..."<<endl;
	cout<<"Adding toppings:"<<endl;
	for(int i=0; i<toppings.size(); i++)
	{
		cout<<"  "<<toppings[i];
	}
}

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

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

void Pizza::box()
{
	cout<<"Place pizza in official PizzaStore box"<<endl;
}

string Pizza::getName()
{
	return name;
}

NYStyleCheesePizza::NYStyleCheesePizza()
{
	name = "NY Style Sauce and Cheese Pizza";
	dough = "Thin Crust Dough";
	sauce = "Marinara Sauce";
	toppings.push_back("Grated Reggiano Cheese");
}

ChicagoStylePizza::ChicagoStylePizza()
{
	name = "Chicago Style Deep Dish Cheese Pizza";
	dough = "Extra Thick Crust Dough";
	sauce = "Plum Tomato Sauce";
	toppings.push_back("Shredded Mozzarella Cheese");
}

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

Pizza* PizzaStore::orderPizza(string type)
{
	pizza = createPizza(type);//创建pizza,但是这个createPizza方法由子类重写,因此最终<span style="color:#ff0000;">由子类决定返回的Pizza类型</span>

	pizza->prepare();
	pizza->bake();
	pizza->cut();
	pizza->box();

	return pizza;
}

Pizza* NYPizzaStore::createPizza(string type)
{
	if("cheese" == type)
	{
		return new NYStyleCheesePizza();
	}
	else if("veggie" == type)
	{
		return new NYStyleVeggiePizza();
	}
	else if("clam" == type)
	{
		return new NYStyleClamPizza();
	}
}


以上代码的类图:



工厂模式用来封装对象的创建。工厂方法模式通过让子类决定该创建的对象时什么,来达到将对象创建的过程封装的目的。
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
工厂方法模式特点:
将创建对象的代码封装起来,集中在一个对象或方法中,避免代码重复,方便以后维护。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: