设计模式(2) –工厂模式(Factory)
2012-10-01 22:13
543 查看
个人而言我认为工厂模式是应用最为广泛的一种模式了,工厂模式也属于创建型模式,一般来说分为:简单工厂模式、抽象工厂(AbstactFactory)模式。这个模式有什么好处呢?我们可以通过下面这个例子来探讨:
假设工厂生产一些了很多种产品,并且需要为这些产品设计很多的包装,每个产品用来展示用各自的包装设计展示给客户看。于是几年前的我可能就会写出如下的代码:
上面的代码看是没啥问题,但在实际工作中我们会遇到这样问题:
今天产品A换了新的包装,那么我们就必须得把A 代码进行修改,同时新增一个新的外形设计类或者直接修改旧的设计类CProductAShow代码,或者我们同一个产品面对不同的地区希望生产不同的外观的产品,那么这时候我们又要怎么去修改呢?
针对上面的问题,我们可能就要和设计师交流,告诉设计师我们需要一个怎样的产品,,从代码角度上说我们就需要考虑一个比较通用的接口来实现代码了,尽量使代码减少耦合,这个时候我们可以进行这样的修改:
代码01:
输出:
可以看出要通过上面的方法,我们引进了外观设计者这个人(其实他就是一个产生外观对象的工厂)--工厂模式在这里体现出现了!!我们只需要告诉设计师我们需要什么类型的产品外观,他就会给我们返回一个通用接口的外观设计了,这样可以比较简单的实现了自己的产品的新外观需求了,基本上我们不需要更改ProductANG1们的代码,只需要新增设计者的类型就可以了。这边有一个需要注意的一点是关于继承类的释放,通常是一个比较容易犯错误的地方,容易引起一些内存未释放,这里我采用的是对函数指针的赋值,使其指向对应的释放函数就可以避免这样的问题产生了。
事情发展到了这步好像可以达到我们的需求了,这个时候工厂又来了一个设计师,他设计的产品相对原来的设计师各有特色,于是客户有的指定设计师A 设计他们的产品外观,有的则希望用新来的设计师B 来设计他们要的产品。这样麻烦有来了,我们又需要去修改ProductANG1的代码了 ,悲剧啊
,为神马程序猿要面对这么多样的需求呢?
为了一次解决这类问题,我们需要一个更大的boss(总设计师)来让设计师们去做对应的事情了,为了减少代码的耦合性,我们再次将外观分开为每个设计师独有的形式,我们称这个boss为抽象工厂。
代码如下:
// 新的外观显示类
ShowBaseNG2.h:
// 设计师们
Designer.h
通过总设计师的控制,我们可以比较清楚的将各个外观分配给产品显示,提高后期的维护效率,但是显然这样也增加了类的个数。
下面展示一下本片文章的类图示意图:
第一个想法:
从图可以看出产品和外观是耦合在在一起的,具有一定的耦合性。
普通工厂:
可以看出这个时候产品已经和外观通过一个base来建立连接了。减少了代码的耦合性。
抽象工厂:
我们可以看到:实际上,AbstractFactory模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory模式正如我在相应的文档中分析的是为一类对象提供创建接口。可以说AbstractFactory是Factory的一种拓展特例吧。
凌晨一点半了,有点累了,睡觉啦了。说的不对之处,欢迎拍砖 ,明天起来上传本文源码。。
转载请注明来自:http://blog.csdn.net/zerolxl
代码下载
假设工厂生产一些了很多种产品,并且需要为这些产品设计很多的包装,每个产品用来展示用各自的包装设计展示给客户看。于是几年前的我可能就会写出如下的代码:
class CProductAShow { public: void AShow() { cout<<"产品A的外观"<<endl; } // ...其他的展示外观 }; class CProductA { public: void ShowA() { m_show.AShow(); } private: CProductAShow m_show; };
上面的代码看是没啥问题,但在实际工作中我们会遇到这样问题:
今天产品A换了新的包装,那么我们就必须得把A 代码进行修改,同时新增一个新的外形设计类或者直接修改旧的设计类CProductAShow代码,或者我们同一个产品面对不同的地区希望生产不同的外观的产品,那么这时候我们又要怎么去修改呢?
针对上面的问题,我们可能就要和设计师交流,告诉设计师我们需要一个怎样的产品,,从代码角度上说我们就需要考虑一个比较通用的接口来实现代码了,尽量使代码减少耦合,这个时候我们可以进行这样的修改:
代码01:
//构造一个外观设计基类 class CShowBase { public: virtual void Show()=0; virtual ~CShowBase() { cout<<"释放基类自己的内容"<<endl; } }; class CProductAShowNG1:public CShowBase { public: void Show() { cout<<"NG1 产品A的外观"<<endl; } ~CProductAShowNG1() { cout<<"释放 NG1 产品A的外观"<<endl; } static void Release( CShowBase *p ) { delete (CProductAShowNG1*)p; } // ...其他的展示外观 }; class CProductAShowNG2:public CShowBase { public: void Show() { cout<<"NG2 产品A的外观"<<endl; } ~CProductAShowNG2() { cout<<"释放 NG2 产品A的外观"<<endl; } static void Release(CShowBase *p) { delete (CProductAShowNG2*)p; } // ...其他的展示外观 }; typedef void (*Release) (CShowBase *) ; // 释放外形设计的指针 // 引进外形设计师来了,这个其实就是一个工厂,因为只要你告诉他们需求类型,他们就会生产了各种各样的外观设计 class CDesigner { public: static CShowBase* CreateShowed(int nType ,Release *prel) { if(nType == 1) //外形1 { if (prel != NULL) *prel = CProductAShowNG1::Release; return new CProductAShowNG1(); //外形1 } else if(nType == 2) { if (prel != NULL) *prel = CProductAShowNG2::Release; // 资源释放指针 return new CProductAShowNG2(); //外形2 } // 默认外形1 return new CProductAShowNG1(); } }; class CProductANG1 { public: CProductANG1(int type) { m_pshow=NULL; m_pshow=CDesigner::CreateShowed(type,&m_ReleaseShow); } ~CProductANG1() { if (m_pshow) { m_ReleaseShow(m_pshow); } } void ShowA() { m_pshow->Show(); } private: CShowBase *m_pshow; Release m_ReleaseShow; // }; int _tmain(int argc, _TCHAR* argv[]) { CProductA oPA; oPA.ShowA(); { CProductANG1 oPNGA(1); oPNGA.ShowA(); } CProductANG1 oPNGA2(2); oPNGA2.ShowA(); getchar(); return 0; }
输出:
可以看出要通过上面的方法,我们引进了外观设计者这个人(其实他就是一个产生外观对象的工厂)--工厂模式在这里体现出现了!!我们只需要告诉设计师我们需要什么类型的产品外观,他就会给我们返回一个通用接口的外观设计了,这样可以比较简单的实现了自己的产品的新外观需求了,基本上我们不需要更改ProductANG1们的代码,只需要新增设计者的类型就可以了。这边有一个需要注意的一点是关于继承类的释放,通常是一个比较容易犯错误的地方,容易引起一些内存未释放,这里我采用的是对函数指针的赋值,使其指向对应的释放函数就可以避免这样的问题产生了。
事情发展到了这步好像可以达到我们的需求了,这个时候工厂又来了一个设计师,他设计的产品相对原来的设计师各有特色,于是客户有的指定设计师A 设计他们的产品外观,有的则希望用新来的设计师B 来设计他们要的产品。这样麻烦有来了,我们又需要去修改ProductANG1的代码了 ,悲剧啊
,为神马程序猿要面对这么多样的需求呢?
为了一次解决这类问题,我们需要一个更大的boss(总设计师)来让设计师们去做对应的事情了,为了减少代码的耦合性,我们再次将外观分开为每个设计师独有的形式,我们称这个boss为抽象工厂。
代码如下:
// 新的外观显示类
ShowBaseNG2.h:
/* 版权说明: 本代码版权 为 糙级码lee 所有 转载请注明来自:http://blog.csdn.net/zerolxl */ #ifndef __SHOW_TYPE_H__ #define __SHOW_TYPE_H__ class CShowBaseNG2 { public: virtual void Show()=0; virtual ~CShowBaseNG2(){}; }; class CProductShowByDesA: public CShowBaseNG2 { public: void Show(); virtual ~CProductShowByDesA(); }; class CProductShowByDesB: public CShowBaseNG2 { public: virtual void Show(); virtual ~CProductShowByDesB(); }; #endif //__SHOW_TYPE_H__ShowBaseNG2.cpp:
#include "stdafx.h" #include "ShowBaseNG2.h" #include "string" #include "iostream" using namespace std; void CProductShowByDesA::Show() { cout<<"设计师A 设计出产品 "<<endl; } CProductShowByDesA::~CProductShowByDesA() { cout<<"释放CProductShowByDesA基类自己的内容"<<endl; } void CProductShowByDesB::Show() { cout<<"设计师B 设计出产品 "<<endl; } CProductShowByDesB::~CProductShowByDesB() { cout<<"释放CProductShowByDesB基类自己的内容"<<endl; }
// 设计师们
Designer.h
/* 版权说明: 本代码版权 为 糙级码lee 所有 转载请注明来自:http://blog.csdn.net/zerolxl */ #ifndef __FACTORY_TYPE_H__ #define __FACTORY_TYPE_H__ class CShowBaseNG2; // 是设计师的基类 可看做总设计师 class CAbstractDesignerBase { public: virtual ~CAbstractDesignerBase(); virtual CShowBaseNG2* CreateShow() = 0; CAbstractDesignerBase(){}; }; // 设计师A 的作品 class CDesignerA:public CAbstractDesignerBase { public: ~CDesignerA(); CDesignerA(); CShowBaseNG2* CreateShow(); }; // 设计师B 的作品 class CDesignerB:public CAbstractDesignerBase { public: ~CDesignerB(); CDesignerB(); CShowBaseNG2* CreateShow(); }; #endif //__FACTORY_TYPE_H__Designer.cpp:
#include "stdafx.h" #include "Designer.h" #include "ShowBaseNG2.h" #include "string" #include "iostream" using namespace std; CAbstractDesignerBase::~CAbstractDesignerBase() { cout<<"释放总设计师开辟的空间"<<endl; } CDesignerA::~CDesignerA() { cout<<"释放设计师A 开辟的空间"<<endl; } CDesignerA::CDesignerA() { } CShowBaseNG2* CDesignerA::CreateShow() { return new CProductShowByDesA(); } CDesignerB::~CDesignerB() { cout<<"释放设计师B 开辟的空间"<<endl; } CDesignerB::CDesignerB() { } CShowBaseNG2* CDesignerB::CreateShow() { return new CProductShowByDesB(); }
int _tmain(int argc, _TCHAR* argv[]) { { CAbstractDesignerBase *pDesigner=new CDesignerA(); CShowBaseNG2 *pShow=pDesigner->CreateShow(); pShow->Show(); delete pDesigner; } { CAbstractDesignerBase *pDesigner=new CDesignerB(); CShowBaseNG2 *pShow=pDesigner->CreateShow(); pShow->Show(); delete pDesigner; } getchar(); return 0; }输出:
通过总设计师的控制,我们可以比较清楚的将各个外观分配给产品显示,提高后期的维护效率,但是显然这样也增加了类的个数。
下面展示一下本片文章的类图示意图:
第一个想法:
从图可以看出产品和外观是耦合在在一起的,具有一定的耦合性。
普通工厂:
可以看出这个时候产品已经和外观通过一个base来建立连接了。减少了代码的耦合性。
抽象工厂:
我们可以看到:实际上,AbstractFactory模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory模式正如我在相应的文档中分析的是为一类对象提供创建接口。可以说AbstractFactory是Factory的一种拓展特例吧。
凌晨一点半了,有点累了,睡觉啦了。说的不对之处,欢迎拍砖 ,明天起来上传本文源码。。
转载请注明来自:http://blog.csdn.net/zerolxl
代码下载
相关文章推荐
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- 设计模式-工厂模式(Factory)
- 设计模式-工厂模式(Factory Pattern)
- 设计模式---工厂模式Factory(创建型)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- 设计模式-工厂模式[Factory]
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- 设计模式--工厂模式Factory
- 【设计模式】工厂模式(Factory Pattern)
- Android设计模式之一个例子让你彻底明白工厂模式(Factory Pattern)
- Java设计模式 创建模式-工厂模式(Factory)
- java设计模式之一工厂模式(Factory Method)
- java设计模式之一工厂模式(Factory Method)
- Head First 设计模式 (四) 工厂模式(factory pattern) C++实现
- java设计模式之一工厂模式(Factory Method)
- 设计模式(四)-工厂模式(Factory Method Pattern/Factory Pattern)——将实例的生成交给子类
- 设计模式——工厂模式(Factory Method)