模式四:工厂模式(Factory Pattern)——封装对象的创建

1.简单工厂

首先从简单工厂开始吧,简单工厂不是一个设计模式,反而比较像一种编程习惯,使用非常频繁。

应用分析

对象有一系列接口,但对象的创建可能是需要经常变化的地方,而对象的创建与实际的具体类型相关紧密,因此,我们将对象的创建封装在工厂类中,由它专门负责对象的创建,而且创建对象的方法可以声明为工厂类的静态方法,这样我们在使用对象的过程中,可以根据接口编程,分离了变化部分与不变部分,便于维护。

实例分析——Pizza店做好不同口味的Pizza,进行出售,Pizza的准备,烘烤,切块,打包流程一样,不同的Pizza需要不同的加工方案,而且Pizza的种类经常扩展,这样我们将不同Pizza加工分离出来,由Pizza工厂完成,Pizza店只是根据客户需求按不变的流程提供满足客户口味的Pizza。

代码分析

//Pizza.h
//具体Pizza类
#ifndef PIZZA_H
#define PIZZA_H

#include <iostream>

//Pizza接口
class Pizza
{
public:
	virtual void prepare() = 0;
	virtual void bake() = 0;
	virtual void cut() = 0;
	virtual void box() = 0;
};

//三个具体的pizza类
class CheesePizza:public Pizza
{
public:
	void prepare()
	{
		std::cout<<"CheesePizza prepare"<<std::endl;
	}
	void bake()
	{
		std::cout<<"CheesePizza bake"<<std::endl;
	}
	void cut()
	{
		std::cout<<"CheesePizza cut"<<std::endl;
	}
	void box()
	{
		std::cout<<"CheesePizza box"<<std::endl;
	}
};

class ClamPizza:public Pizza
{
public:
	void prepare()
	{
		std::cout<<"ClamPizza prepare"<<std::endl;
	}
	void bake()
	{
		std::cout<<"ClamPizza bake"<<std::endl;
	}
	void cut()
	{
		std::cout<<"ClamPizza cut"<<std::endl;
	}
	void box()
	{
		std::cout<<"ClamPizza box"<<std::endl;
	}
};

class VeggiePizza:public Pizza
{
public:
	void prepare()
	{
		std::cout<<"VeggiePizza prepare"<<std::endl;
	}
	void bake()
	{
		std::cout<<"VeggiePizza bake"<<std::endl;
	}
	void cut()
	{
		std::cout<<"VeggiePizza cut"<<std::endl;
	}
	void box()
	{
		std::cout<<"VeggiePizza box"<<std::endl;
	}
};

#endif



//PizzaFactory.h
//Pizza工厂
#ifndef PIZZASTORE_H
#define PIZZASTORE_H

#include "Pizza.h"

class PizzaFactory//简单工厂
{
public:
	static Pizza * createPizza(std::string type)
	{
		Pizza *PtrPizza=NULL;
		if(!type.compare("Cheese")) PtrPizza=new CheesePizza();
		else if(!type.compare("Clam")) PtrPizza=new ClamPizza();
		else if(!type.compare("Veggie")) PtrPizza=new VeggiePizza();
		return PtrPizza;
	}
};

#endif



//PizzaStore.h
//Pizza店
#ifndef PIZZAFACTORY_H
#define PIZZAFACTORY_H

#include "Pizza.h"
#include "PizzaFactory.h"

class PizzaStore
{
public:
	Pizza * orderPizza(std::string type)//根据客户需求,按标准化流程提供Pizza
	{
		Pizza *res=PizzaFactory::createPizza(type);
		if(!res) return res;
		res->prepare();
		res->bake();
		res->cut();
		res->box();
		return res;
	}
};

#endif


//Main.cpp
//测试程序
#include <iostream>
#include "PizzaStore.h"

int main()
{
	PizzaStore *temStore=new PizzaStore();//创建Pizza店
	temStore->orderPizza("Cheese");//根据客户需求生产Pizza
	return 0;
}


2.工厂方法模式

定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

应用分析

所有的工厂模式都是用来封装对象的创建。工厂方法模式通过让子类决定创建的对象是什么,来达到对象创建过程的封装目的。这样,客户程序中关于超类的代码和子类对象创建代码解耦。

实例分析——同上,每个Pizza店可能加工Pizza的方法不同,需要有自己特有的Pizza加工方法,而由于Pizza处理过程一致,这样可以声明Pizza店的接口,而Pizza的生产过程,在具体Pizza店子类中,具体确定。

代码分析

//Pizza.h
//具体Pizza类
#ifndef PIZZA_H
#define PIZZA_H

#include <iostream>

//Pizza接口
class Pizza
{
public:
	virtual void prepare() = 0;
	virtual void bake() = 0;
	virtual void cut() = 0;
	virtual void box() = 0;
};

//三个具体的pizza类
class CheesePizza:public Pizza
{
public:
	void prepare()
	{
		std::cout<<"CheesePizza prepare"<<std::endl;
	}
	void bake()
	{
		std::cout<<"CheesePizza bake"<<std::endl;
	}
	void cut()
	{
		std::cout<<"CheesePizza cut"<<std::endl;
	}
	void box()
	{
		std::cout<<"CheesePizza box"<<std::endl;
	}
};

class ClamPizza:public Pizza
{
public:
	void prepare()
	{
		std::cout<<"ClamPizza prepare"<<std::endl;
	}
	void bake()
	{
		std::cout<<"ClamPizza bake"<<std::endl;
	}
	void cut()
	{
		std::cout<<"ClamPizza cut"<<std::endl;
	}
	void box()
	{
		std::cout<<"ClamPizza box"<<std::endl;
	}
};

class VeggiePizza:public Pizza
{
public:
	void prepare()
	{
		std::cout<<"VeggiePizza prepare"<<std::endl;
	}
	void bake()
	{
		std::cout<<"VeggiePizza bake"<<std::endl;
	}
	void cut()
	{
		std::cout<<"VeggiePizza cut"<<std::endl;
	}
	void box()
	{
		std::cout<<"VeggiePizza box"<<std::endl;
	}
};

#endif


//PizzaStore.h
//Pizza店
#ifndef PIZZAFACTORY_H
#define PIZZAFACTORY_H

#include "Pizza.h"

class PizzaStore
{
public:
	Pizza * orderPizza(std::string type)//根据客户需求,按标准化流程提供Pizza
	{
		Pizza *res=CreatePizza(type);
		if(!res) return res;
		res->prepare();
		res->bake();
		res->cut();
		res->box();
		return res;
	}
protected:
	virtual Pizza * CreatePizza(std::string type)=0;//定义接口,由子类具体决定要实例化的类是哪一个
};


class NYPizzaStore:public PizzaStore//纽约Pizza店,生成纽约Pizza
{
protected:
	Pizza * CreatePizza(std::string type)
	{
		Pizza *PtrPizza=NULL;
		if(!type.compare("Cheese")) PtrPizza=new CheesePizza();
		else if(!type.compare("Clam")) PtrPizza=new ClamPizza();
		return PtrPizza;;
	}
};


class ChicagoPizzaStore:public PizzaStore//芝加哥Pizza店,生成芝加哥Pizza
{
protected:
	Pizza * CreatePizza(std::string type)
	{
		Pizza *PtrPizza=NULL;
		if(!type.compare("Cheese")) PtrPizza=new CheesePizza();
		else if(!type.compare("Veggie")) PtrPizza=new VeggiePizza();
		return PtrPizza;
	}
};

#endif


//Main.cpp
//测试程序
#include <iostream>
#include "PizzaStore.h"

int main()
{
	PizzaStore *ps=new NYPizzaStore();
	ps->orderPizza("Clam");
	delete ps;
	ps=NULL;

	ps=new ChicagoPizzaStore();
	ps->orderPizza("Veggie");
	delete ps;
	ps=NULL;	

	return 0;
}


3.抽象工厂模式

提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指明具体类。

应用分析

一个类型由不同成分组成,成分具体不同可以组成不同类型的对象,抽象工厂可以定义生产这些成分的公共接口,而具体的工厂实现具体成分的生产。

实例分析——同上,各个区域Pizza的原料成分类型相似,但具体不同,不同的Pizza原料生产工厂负责具体原料的生产。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值