C++三种工厂模式介绍及其区别

工厂模式有三种,分别是:简单工厂模式工厂模式抽象工厂模式


要理解为什么要用工厂模式,首先我们要这样编程:例如一家游戏公司已经写好了 飞机类文件,坦克类文件,潜艇类文件,并把他们封装好让程序员们来调用(姑且把封装好的文件叫库文件),而程序员调用来写程序,姑且把程序员叫做使用者。好,理解这句话我们就继续往下说。

无论哪种工厂模式,都不会给你直接 new 具体的产品对象的。使用者能做的只是操作两个接口--->抽象产品对象和抽象工厂对象。那这里又怎么理解呢?

以战争游戏为例,使用工厂模式的话,调用者(一般调用库文件写main的程序员)不能直接 new(创建) 出坦克对象或者飞机对象,他能new的只是一个武器对象(抽象产品类),然后通过对武器对象(抽象产品类)操作,来获得一个具体的武器对象,如坦克对象,如飞机对象,这里用的操作方法就是多态了,所以工厂模式处处都有多态。

而抽象工厂也是同样理解,工厂生成产品,所以这里我们可以把抽象工厂类看成一个武器车间对象,根据使用者(程序员)的操作,可以通过多态把武器车间设置成坦克车间对象,飞机车间对象。而记住,程序员是不可以直接 new出坦克车间的,这是工厂模式设计出来所避免的东西。


看到这里,相信大家会有疑问,为什么就不允许直接 new 出坦克对象,飞机对象等具体的对象呢?

因为试想一下,一个战争游戏,只有一个车间,步兵从那里出,坦克从那里出,飞机从那里出,造成的后果就是大量的代码混杂在一起,增加维护难度。

而且设计模式有一个原则就是面向接口编程,倾向于把一切封装起来,只露出接口,这样的好处是代码管理,维护方便。



下面介绍简单工厂模式:简单工厂模式一般比较少用,因为本身有较大缺点。其优点就是不用记那么多类名,只要传入对应表示参数就能创建对应类了,

例如1表示坦克,就参数type=1,2等于飞机,就type=2,等待再讲缺点在哪


简单工厂模式:

简单工厂一般向工厂对象传入参数type来决定生产哪种产品。


#include<iostream>
using namespace std;

/*以战争游戏为例*/ 
class AbstractProduct  //抽象武器类 
{
	public:
	virtual void operation()=0; 	
} ;

class AbstractFactory	//抽象车间 
{
	public:
	virtual AbstractProduct *createproduct(int type)=0;
};

class ProductA:public AbstractProduct	//坦克类 
{
	public:
	void operation()
	{
		cout<<"this is ProductA"<<endl;
	}	
};

class ProductB:public AbstractProduct	//飞机类 
{
	public:
	void operation()
	{
		cout<<"this is productB"<<endl;
	}	
};

/*大武器车间,其实这里不用抽象工厂也行,直接用SimpleFactory类也可以
但是设计模式都要抽象,所以按规矩就写一下抽象工程类。*/ 
class SimpleFactory:public AbstractFactory	
{
	public:
	AbstractProduct *createproduct(int type)
	{
		if(type == 1)
			return new ProductA();
		if(type == 2)
			return new ProductB();
	}		
};

int main()
{
	AbstractProduct *p = NULL;
	AbstractFactory *f = NULL;
	f = new SimpleFactory();
	p = f->createproduct(1);	//当type=1时,创建产品A对象,type=2,创建产品B 
	p->operation();
	return 0;
}

为什么说简单工厂模式一般不用,因为它违反了设计模式的 开闭原则。

什么叫开闭原则呢?

就是对代码模块,允许扩展,就是增加代码量,但现在的代码不允许修改。


想想简单工厂模式,如果我要增加导弹类武器,怎么办?只能修改SimpleFactory类中的代码,增加 if(type=3),就new一个导弹类。

这本质上修改了SimpleFactory代码模块。下面要讲的第二种工厂模式---工厂模式就可以解决这个问题。



工厂模式:


#include<iostream>
using namespace std;

class AbstractWeapon			//抽象武器类 
{
	public:
	virtual void operation()=0;	
};

class J10:public AbstractWeapon		//J10战斗机 
{
	public:
	void operation()
	{
		cout<<"this is J10"<<endl;
	}
};

class F22:public AbstractWeapon		//F22战斗机 
{
	public:
	void operation()
	{
		cout<<"this is F22"<<endl;
	}
};

class Tank1:public AbstractWeapon	//一号坦克 
{
	public:
	void operation()
	{
		cout<<"this is T1"<<endl;
	}	
};


///
class AbstractFactory				//抽象工厂 
{
	public:
	virtual AbstractWeapon *create1()=0;	
	virtual AbstractWeapon *create2()=0;
};

class PlaneFactory:public AbstractFactory	//飞机工厂 
{
	public:
	AbstractWeapon *create1()
	{
		return new J10();		
	}	
	
	AbstractWeapon *create2()
	{
		return new F22();
	}
};

class TankFactory:public AbstractFactory	//坦克工厂 
{
	public:
	AbstractWeapon *create1()
	{
		return new Tank1();
	}	
	
	AbstractWeapon *create2()
	{
	
	}
};




int main()
{
	AbstractWeapon *p=NULL;
	AbstractFactory *f = NULL;
	f = new TankFactory();		//选择坦克工厂 
	//f = new PlaneFactory;    //选择飞机工厂 
	p = f->create1();
	p->operation();
	return 0;
}
/*打印结果:This is T1*/ 

由上面代码可知,通过增加多态的代码,可以扩展多一种工厂来生产新一类产品,从而不需要改动原来的代码模块,因为当你的代码量多的话,轻易改代码模块是很高风险的。上面的抽象工厂类相当于所有具体工厂的规格要求,如上,我在抽象工厂定义了2个纯虚函数用于创建对象,就是说,所有的具体工厂最多只能创建2种不同的武器,如(J10,F22),当然一种也可以,如坦克类就只有一号坦克。你想创建多种不同的武器,往抽象类中加纯虚函数即可


但这种工厂模式也是有缺陷的,就是一种工厂只能生产一类产品,如飞机工厂,只能生成各种飞机。

相信大家都玩过红色境界,例如现在有中美两个国家,中国有自己的飞机坦克,美国也有自己的飞机坦克,那我们实现的时候,绝不能在美国工厂能生成中国工厂的东西。

而抽象工厂模式能有一个更好的分类功能



抽象工厂模式:

抽象工厂可以使一类工厂生产不同类的的产品,但这些产品都有一定的联系。


#include<iostream>
using namespace std;

class AbstractPlane			//抽象飞机类 
{
	public:
	virtual void operation()=0;
};

class J10:public AbstractPlane	//中国J10战斗机 
{
	public:
	void operation()
	{
		cout<<"this is J10"<<endl;
	}	
};

class F22:public AbstractPlane	//美国F22战斗机 
{
	public:
	void operation()
	{
		cout<<"this is F22"<<endl;
	}	
};
//
class AbstractTank			//抽象坦克类 
{
	public:
	virtual void operation()=0;	
};

class China_Tank:public AbstractTank	//中国坦克 
{
	public:
	void operation()
	{
		cout<<"this is china tank"<<endl;
	}	
};

class USA_Tank:public AbstractTank		//美国坦克 
{
	public:
	void operation()
	{
		cout<<"this is USA Tank"<<endl;
	}
};
/
class AbstractFactory			//抽象工厂类 
{
	public:
	virtual AbstractPlane *CreatePlane()=0;
	virtual AbstractTank *CreateTank()=0;
};

class China_Factory:public AbstractFactory		//中国工厂 
{
	public:
	AbstractPlane *CreatePlane()
	{
		return new J10();
	}
	
	AbstractTank *CreateTank()
	{
		return new China_Tank();
	}	
};

class USA_Factory:public AbstractFactory		//美国工厂 
{
	public:
	AbstractPlane *CreatePlane()
	{
		return new F22();
	}
	
	AbstractTank *CreateTank()
	{
		return new USA_Tank();
	}	
};

///
int main()
{
	AbstractPlane *plane = NULL;		
	AbstractTank *tank = NULL;
	AbstractFactory *factory = NULL;	
		
	factory = new China_Factory();		//生成中国工厂 
	plane = factory->CreatePlane();		//生成中国的飞机 
	plane->operation();					//调用中国飞机的方法 
	return 0;
}
/*打印结果:This is J10*/ 





























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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值