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

工厂(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();
	}
}

以上代码的类图:
工厂模式用来封装对象的创建。 工厂方法模式通过让子类决定该创建的对象时什么,来达到将对象创建的过程封装的目的
工厂方法模式 定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
工厂方法模式特点:
将创建对象的代码封装起来,集中在一个对象或方法中,避免代码重复,方便以后维护。













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值