设计模式之工厂模式 c++实现和详细分析

 工厂模式

 

<1>  介绍:

目的:主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

工厂模式分为三类:
1)简单工厂模式(Simple Factory)

2)工厂方法模式(Factory Method)

3)抽象工厂模式(Abstract Factory)

 GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

<2>简单工厂模式

组成:

1)        工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑。在java中它往往由一个具体类实现。

2)        抽象产品角色:它一般是具体产品继承的父类或者实现的接口。在java中由接口或者抽象类来实现。

3)        具体产品角色:工厂类所创建的对象就是此角色的实例。在java中由一个具体类实现。

结构图

对产品部分来说,它是符合开闭原则的;但是工厂部分不太理想,因为每增加一类产品,都要在工厂类中增加相应的业务逻辑或者判断逻辑,这显然是违背开闭原则的。 因此需要后面的工厂方法模式去解决

简单工厂的应用场景:

1当工厂类负责创建的对象比较少时可以考虑使用简单工厂模式()

2客户如果只知道传入工厂类的参数,对于如何创建对象的逻辑不关心时可以考虑使用简单工厂模式

 

简单工厂模式

 

#include <iostream>
using namespace std;
/****************************************
*本程序用来测试分析工厂模               *
此程序为简单工厂模式
  2014.5.10 10:16 
*****************************************/
class Product
{
public:
	 virtual void property()
	 {
		 cout<<"i am product!"<<endl;
	 }
};

class Product1:public Product
{
public :
	void property()
	{
		cout << "i am product 1" << endl;
	}
};

class Product2: public Product
{
public :
	void property()
	{
		cout << "i am product 2" << endl;
	}
};

class factory
{
public:
	Product* GetProduct(int SelectProduct) 
	{	
		 switch(SelectProduct)
		 {
		 case 1 : return new Product1;  break;
		 case 2:  return new Product2; break;
		 default: 
			 {
					cout << "something is wrong so return product" << endl;
					return new Product;
				    break;
			 }
		 }	 
}
 
};
int main()
{
	int sel =1;
	factory fac;
	Product *p = fac.GetProduct(1);
	p->property();
	delete p;
	p = NULL;
	p = fac.GetProduct(2);
	p->property();
	delete p;
	p = NULL;
	p = fac.GetProduct(3);
	p->property();
	delete p;
	p = NULL;
	return 0;
}

简单工厂模式的优缺点

优点 
1.工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。 
缺点 
1.系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。 


<3>工厂方法模式

引入原因 :简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而工厂方法模式可以解决简单工厂模式中存在的这个问题。

组成:

1)        抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。c++中由抽象类实现

2)        具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

3)        抽象产品角色:它是具体产品继承的父类或者是实现的接口。 由抽象类或者接口来实现。

4)        具体产品角色:具体工厂角色所创建的对象就是此角色的实例。 由具体的类来实现。

UML结构图


工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式就可以允许系统不修改工厂类逻辑的情况下来添加新产品,这样也就克服了简单工厂模式中缺点。

具体代码如下:

#include <iostream>
using namespace std;
/****************************************
*        工厂方法模式演示程序             *
*          2014.5.22 17:16               *
*	     by hnust_xiehonghao             *
*****************************************/
class Product
{
public:
	 virtual void property()
	 {
		 cout<<"i am product!"<<endl;
	 }
};

class Product1:public Product
{
public :
	void property()
	{
		cout << "i am product 1" << endl;
	}
};

class Product2: public Product
{
public :
	void property()
	{
		cout << "i am product 2" << endl;
	}
};

class Factory
{
public: 
    virtual Product* GetProduct() = 0;
};

class Factory1 : public Factory
{
public:
        Product* GetProduct()
		{
			return new Product1();

		}
};

class Factory2 : public Factory
{
public :
        Product* GetProduct()
		{
			return new Product2();

		}
};

int main()
{
	 Factory* Fac1 = new Factory1();//产生什么类型的产品就生成什么类型的工厂 让这种类型的工厂生成该产品
     Product* Product1 = Fac1->GetProduct();
	 Product1->property();
	 delete Fac1;
	 delete Product1;
	 Factory* Fac2 = new Factory2();
	 Product* Product2 = Fac2->GetProduct();
	 Product2->property();
	 delete Fac2;
	 delete Product2;
	 

    return 0;
}

常用场景
  1. 在设计的初期,就考虑到产品在后期会进行扩展的情况下,可以使用工厂方法模式;
  2. 产品结构较复杂的情况下,可以使用工厂方法模式;
<4>抽象工厂模式

作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。  节省了需要建立的工厂数目 便于管理和扩展
先了解一下一个名词   产品族:   位于不同产品等级结构中,功能相关联的产品组成的家族。
例如 宝马和奔驰 可以归为一个产品族 都是跑车族的   或者说 有一个生产显示屏的工厂 现在想再建一个工厂生产与显示屏配套服务的东西。我们可以把2者归为一个族 用一个工厂去完成2者  这就是抽象工厂

抽象工厂模式中的有以下的四种角色:


抽象工厂( Abstract Factory )角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
具体工厂( Concrete Factory )角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
抽象产品( Abstract Product )角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
具体产品( Concrete Product )角色:这个角色用以代表具体的产品。
 
结构图:
 
 
如图所示,抽象工厂模式,就好比是两个工厂方法模式的叠加。抽象工厂创建的是一系列相关的对象,其中创建的实现其实就是采用的工厂方法模式。
适用场合

工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。

 

#include <iostream>
using namespace std;
/****************************************
*          工厂方法模式演示程序           *
* 以食品和餐具作比喻 若不够形象请尽情吐槽  *
*            偶会尽力修改                * 
*          2014.5.22 17:16              *
*	     by hnust_xiehonghao            *
*****************************************/
class ProductA//A可以看做是高档牛排
{
public:
	 virtual void property()
	 {
		 cout<<"我是牛排!"<<endl;
	 }
};

class ProductA1:public ProductA
{
public :
	void property()
	{
		cout << "我是高档牛排" << endl;
	}
};

class ProductA2: public ProductA
{
public :
	void property()
	{
		cout << "我是低档牛排" << endl;
	}
};

class ProductB//我是餐具  叉子
{
public:
	 virtual void property()
	 {
		 cout<<"我是餐具!"<<endl;
	 }
};

class ProductB1:public ProductB
{
public :
	void property()
	{
		cout << "我是银餐具" << endl;
	}
};

class ProductB2: public ProductB
{
public :
	void property()
	{
		cout << "我是钢餐具" << endl;
	}
};



class Factory//抽象工厂 一个工厂是可以生产 高档 和 低档 这两类产品的
{
public: 
    virtual ProductA* GetProductA() = 0;//产生牛排
	virtual ProductB* GetProductB() = 0;//产生餐具
};

class Factory1 : public Factory//产生高档产品子工厂	
{
public:
        ProductA* GetProductA()
		{
			return new ProductA1();

		}
	    ProductB* GetProductB()
		{
			return new ProductB1();

		}
};

class Factory2 : public Factory// 产生低档 产品
{
public:
        ProductA* GetProductA()
		{
			return new ProductA2();

		}
	    ProductB* GetProductB()
		{
			return new ProductB2();

		}
};

int main()
{
	 Factory* Fac1 = new Factory1(); 
     ProductA* ProductA1 = Fac1->GetProductA();
	 ProductB* ProductB1 = Fac1->GetProductB();
	 ProductA1->property();
	 ProductB1->property();
	 delete Fac1;
	 delete ProductA1;
	 delete ProductB1;
 	 Factory* Fac2 = new Factory2(); 
     ProductA* ProductA2 = Fac1->GetProductA();
	 ProductB* ProductB2 = Fac1->GetProductB();
	 ProductA2->property();
	 ProductB2->property();
	 delete Fac2;
	 delete ProductA2;
	 delete ProductB2;

    return 0;
}


 

 

 



 

简单工厂 与 策略模式 的小区别

#include <iostream>
using namespace std;
/****************************************
*本程序用来测试分析工厂模式与策略模式的区别*
此程序为策略模式
  2014.5.10 14:31 
*****************************************/
class Product
{
public:
	 virtual void property()
	 {
		 cout<<"i am product!"<<endl;
	 }
};

class Product1:public Product
{
public :
	void property()
	{
		cout << "i am product 1" << endl;
	}
};

class Product2: public Product
{
public :
	void property()
	{
		cout << "i am product 2" << endl;
	}
};
 
class  select
{
public:
     select (Product *pro) 
	 {	
		  product = pro;
	 }
	void property()
	{
		product->property();
	}
private:
	Product *product;
};
int main()
{
	 Product1 *pro1;
	 Product2 *pro2;
	 pro1 = new Product1;
	 pro2 = new Product2;
	 select *slt1 = new select(pro1);
	 slt1->property();
	 select *slt2 = new select(pro2);
	 slt2->property();
	return 0;
}


参考 http://blog.csdn.net/ai92/article/details/209198

       http://haolloyin.blog.51cto.com/1177454/332576

       http://blog.csdn.net/wuzhekai1985/article/details/6660462

       http://blog.sina.com.cn/s/blog_6ce9e8870101iv79.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值