3.1 抽象工厂

好了,七月的第一篇博客正式标志着我的回归。六月已经过去,七月还是新的!

GOF的书真的不好懂,不知道是我的原因还是我的原因?好吧,既然不懂只能参考csdn博客了:http://blog.csdn.net/u010064842/article/details/9150921

 

简单抽象工厂模式

意图:提供一个接口用来创建一系列相关或者相互依赖的对象,而无需指定它们具体的类。

 

设计模式的学习一定要配合例子。比如说我吃厨师做的食物这件事。食物有很多种,可能是红烧肉,可能是清蒸鱼,每一种特定的食物都是一个具体的类。但是我不需要指定具体的类,我只需要指定一个接口——食物,其中包含了每个具体的食物类的共同的fuction。然后我只要指定厨师类帮我做特定食物类表示的食物就行了。

例子见图:


其实在上图中,厨师就是Factory,食物就是Product。抽象为抽象工厂模式见图:


代码实现:
//产品基类
#ifndef _PRODUCT_H
#define _PRODUCT_H

class Product
{
protected:
	Product(){}
public:
	virtual ~Product(){}
	virtual void function() = 0;
};

#endif

//具体产品A
#ifndef _CONCRETE_PRODUCT_A_H
#define _CONCRETE_PRODUCT_A_H
#include "Product.h"
#include <iostream>
using namespace std;
class ConcreteProductA:public Product
{
public:
	ConcreteProductA()
	{
		cout<<"创建产品A"<<endl;
	}
	virtual ~ConcreteProductA()
	{
		cout<<"释放产品A"<<endl;
	}

	virtual void function()
	{
		cout<<"这是产品A的基本功能"<<endl;
	}

};

#endif


//具体产品B
#ifndef _CONCRETE_PRODUCT_B_H
#define _CONCRETE_PRODUCT_B_H
#include "Product.h"
#include <iostream>
using namespace std;
class ConcreteProductB:public Product
{
public:
	ConcreteProductB()
	{
		cout<<"创建产品B"<<endl;
	}
	virtual ~ConcreteProductB()
	{
		cout<<"释放产品B"<<endl;
	}

	virtual void function()
	{
		cout<<"这是产品B的基本功能"<<endl;
	}

};

#endif

//工厂类:负责具体产品的创建,有两种方式实现产品的创建,
//I、创建不同的产品用不同的方法;II、创建不同产品用相同
//的方法,然后通过传递参数实现不同产品的创建。本实例中
//两种模式都给出了,大家自行分析。
#ifndef _SIMPLE_FACTORY_H
#define _SIMPLE_FACTORY_H

#include "Product.h"
#include "ConcreteProductA.h"
#include "ConcreteProductB.h"
class SimpleFactory
{
public:
	SimpleFactory(){}
	~SimpleFactory(){}
	Product *CreateProduct(int type)
	{
		Product *p = NULL;
		switch(type)
		{
		case 0:
			p = new ConcreteProductA();
			break;
		case 1:
			p = new ConcreteProductB();
			break;
		default:
			p = new ConcreteProductA();
			break;
		}
		return p;
	}

	Product *CreateProductA()
	{
		Product *p = new ConcreteProductA();
		return p;
	}

	Product *CreateProductB()
	{
		Product *p = new ConcreteProductB();
		return p;
	}

};
#endif

//客户端程序
#include <iostream>
#include "SimpleFactory.h"
#include "Product.h"
using namespace std;

int main(int argc, char **argv)
{
	SimpleFactory sf;
	Product *p = sf.CreateProductA();
	p->function();
	delete p;

	
	p = sf.CreateProduct(1);
	p->function();
	delete p;

	system("pause");
	return 0;
}

抽象工厂优点:将客户与类相分离,客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,不出现在客户代码中。

抽象工厂缺点:对修改不封闭,新增加产品您要修改工厂。违法了鼎鼎大名的开闭法则(OCP)。

 

抽象工厂模式的改进

在上面的代码中,如果新出来一个ProductC,那我首先需要创建一个ConcreteProductC类,然后在SimpleFactory类中增加对ConcreteProductC的调用,这需要修改SimpleFactory类,使得这个类不能封闭。

改进方法:将厨师类抽象为一个基类,再增加“做红烧肉的厨师类”,“做清蒸鱼的厨师类”等等,它们分别都继承厨师这个基类。现在来看这个模式发生了变化,结构中多了一个厨师的抽象,抽象并不具体的加工产品了,至于是炖汤还是炖鱼,是由这个抽象工厂的继承子类来实现,现在的模式也就变成工厂方法模式了。这样,如果我新出来一个菜,我不需要修改抽象的厨师类或者其他子类,我只需要增加一个做新菜的厨师类,继承于抽象的厨师类,就可以方便的增加一个菜了。

图示:


代码实现:
在原来的基础上增加:
//抽象的工厂类
#ifndef _FACTORY_H
#define _FACTORY_H

#include "Product.h"
class Factory
{
public:
	Factory(){}
	virtual ~Factory(){}
	virtual Product* CreateProduct(int type=0) = 0;
};
#endif

//具体工厂类:工厂基类的具体实现,由此类决定创建具体产品。
//这里ConcreteFactoryA 对于与图中的工厂实现,ConcreteFactoryB 
//对于与图中的新工厂。
#ifndef _CONCRETE_FACTORY_A_H
#define _CONCRETE_FACTORY_A_H

#include "Factory.h"
class ConcreteFactoryA: public Factory
{
public:
	ConcreteFactoryA(){}
	virtual ~ConcreteFactoryA(){}
	Product *CreateProduct(int type)
	{
		Product *p = NULL;
		switch (type)
		{
		case 0:
			p = new ConcreteProductA();
			break;
		case 1:
			p = new ConcreteProductB();
			break;
		default:
			p = new ConcreteProductA();
			break;
		}
		return p;
	}

};
#endif

//客户端程序
#include <iostream>
#include "SimpleFactory.h"
#include "Product.h"
#include "Factory.h"
#include "ConcreteFactoryA.h"
#include "ConcreteFactoryB.h"
using namespace std;

int main(int argc, char **argv)
{
	Factory *f = new ConcreteFactoryA();
	Product *p = f->CreateProduct(0);
	p->function();
	delete p;

	p = f->CreateProduct(1);
	p->function();
	delete p;
	delete f;

	f = new ConcreteFactoryB();
	p = f->CreateProduct();
	p->function();
	delete p;
	delete f;

	system("pause");
	return 0;
}

当然还可以继续改进,不多说了,见图:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值