首页 c++设计模式(精简版)

c++设计模式(精简版)

举报
开通vip

c++设计模式(精简版)C++设计模式一、功能将一个类的接口转换成客户希望的另外一个接口,解决两个已有接口之间不匹配的问题。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。二、结构图(1)classadapter(2)objectadapter三、实现和其他很多模式一样,学习设计模式的重点是学习每种模式的思想,而不应拘泥于它的某种具体结构图和实现。因为模式是灵活的,其实现可以是千变万化的,只是所谓万变不离其宗。在STL中大量运用了Adapter模式,象functionadapter、iteratoradpter...

c++设计模式(精简版)
C++设计模式一、功能将一个类的接口转换成客户希望的另外一个接口,解决两个已有接口之间不匹配的问题。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。二、结构图(1)classadapter(2)objectadapter三、实现和其他很多模式一样,学习设计模式的重点是学习每种模式的思想,而不应拘泥于它的某种具体结构图和实现。因为模式是灵活的,其实现可以是千变万化的,只是所谓万变不离其宗。在STL中大量运用了Adapter模式,象functionadapter、iteratoradpter,它们与这里说的adapter结构并不一样,但思想是一样的。具体的介绍可到侯捷网站上找相关文章,他讲得非常好。四、示例代码(1)classadapternamespaceDesignPattern_Adapter{//classAdapteeclassAdaptee{public:voidSpecialRequest(){}};//classTargetclassTarget{public:virtualvoidRequest()=0;};//classAdapterclassAdapter:publicTarget,privateAdaptee{public:virtualvoidRequest(){SpecialRequest();}};}客户端代码:{usingnamespaceDesignPattern_Adapter;Target*p=newAdapter();p->Request();//实际上调用的是Adaptee::SpecialRequest()}(2)objectadapternamespaceDesignPattern_Adapter{//classAdapteeclassAdaptee{public:voidSpecialRequest(){}};//classTargetclassTarget{public:virtualvoidRequest()=0;};//classAdapterclassAdapter:publicTarget{public:virtualvoidRequest(){_adaptee.SpecialRequest();}private:Adaptee_adaptee;};}客户端代码:{usingnamespaceDesignPattern_Adapter;Target*p=newAdapter();p->Request();//实际上调用的是Adaptee::SpecialRequest()}六、实例(1)STL中的ClassAdapterSTL中的AdapterClass包括:a.stack(对应的adaptee是deque)。b.queue(对应的adaptee是deque)。c.priority_queue(对应的adaptee是vector)。下面是从VC中的<stack>拷出的stack的类定义:templateclass_Container=deque<_Ty>>classstack{//LIFOqueueimplementedwithacontainerpublic:typedef_Containercontainer_type;typedeftypename_Container::value_typevalue_type;typedeftypename_Container::size_typesize_type;stack():c(){//constructwithemptycontainer}explicitstack(const_Container&_Cont):c(_Cont){//constructbycopyingspecifiedcontainer}boolempty()const{//testifstackisemptyreturn(c.empty());}size_typesize()const{//testlengthofstackreturn(c.size());}value_type&top(){//returnlastelementofmutablestackreturn(c.back());}constvalue_type&top()const{//returnlastelementofnonmutablestackreturn(c.back());}voidpush(constvalue_type&_Val){//insertelementatendc.push_back(_Val);}voidpop(){//eraselastelementc.pop_back();}bool_Eq(conststack<_Ty,_Container>&_Right)const{//testforstackequalityreturn(c==_Right.c);}bool_Lt(conststack<_Ty,_Container>&_Right)const{//testifthis<_Rightforstacksreturn(c<_Right.c);}protected:_Containerc;//theunderlyingcontainer};关键之处在于_Containerc,stack所有的操作都转交给c去处理了。(这实际上就是前面所说的"objectadapter",注意STL中的classadapter与上面所说的classadapter概念不完全一致)stack的使用方法很简单,如下:{intia[]={1,3,2,4};dequeid(ia,ia+4);stackis(id);}(2)近日看了一篇文章“Generic<Programming>:简化异常安全代码”,原文出自http://www.cuj.com/experts/1812/alexandr.htm?topic=experts,中文译文出自"C++View第5期"。文章绝对一流,作者给出的代码中也使用了Adaptor模式,也有一定代表性。我将其问题一般化,概括出以下示例:问题:假设有几个已有类,他们有某些共同的行为,但它们彼此间是独立的(没有共同的基类)。如:classT1{public:voidProc(){}};classT2{public:voidProc(){}};//...如何以统一的方式去调用这些行为呢?解决方法1:很自然的会想到用 模板 个人简介word模板免费下载关于员工迟到处罚通告模板康奈尔office模板下载康奈尔 笔记本 模板 下载软件方案模板免费下载 ,如:template<classT>voidTest(Tt){t.Proc();}的确不错,但这只适用于简单的情况,有时情况是很复杂的,比如我们无法把类型放到模板参数中!解决方法2:困难来自于这些类没有共同的基类,所以我们就创造一个基类,然后再Adapt。//classIAdaptor,抽象基类classIAdaptor{public:virtualvoidProc()=0;};//classAdaptortemplate<classT>classAdaptor:publicIAdaptor,privateT//实现继承{public:virtualvoidProc(){T::Proc();}};//以统一方式调用函数Proc,而不关心是T1、T2或其他什么类voidTest(conststd::auto_ptr&sp){sp->Proc();}客户端代码:Test(std::auto_ptr(newAdaptor));Test(std::auto_ptr(newAdaptor));上例很简单,用方法一中的模板函数就可以很好地解决了。下面是一个略微复杂一点的例子,根据参数类型来创建适当的对象:classT1{public:T1(int){/*...*/}voidProc(){/*...*/}};classT2{public:T2(char){/*...*/}voidProc(){/*...*/}};//classIAdaptor,抽象基类classIAdaptor{public:virtualvoidProc()=0;};//classAdaptortemplateclassAdaptor:publicIAdaptor,privateT//实现继承{public:Adaptor(intn):T(n){}Adaptor(charc):T(c){}virtualvoidProc(){T::Proc();}};classTest{public:Test(intn):sp(newAdaptor(n)){}Test(charc):sp(newAdaptor(c)){}voidProc(){sp->Proc();}private:std::auto_ptrsp;};客户端代码:Testt1(10);t1.Proc();Testt2('c');t2.Proc();上面是示例而非实例,你也许更愿意看看它实际的运用。去下载作者所写的代码,好好欣赏一下吧。C++设计模式之AbstractFactory一、功能提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。二、结构图类厂最基本的结构示意图如下:在实际应用中,类厂模式可以扩充到很复杂的情况,如下图所示:三、优缺点优点:(1)封装创建过程。客户不用知道类厂是如何创建类实例的,类厂封闭了所有创建的细节。这样可选择不同的创建方法,增加了灵活性。(2)将客户与具体类隔离,提高了各自的可重用性。缺点:Factory类层次与具体类层次通常是平行的(即一一对应的)。增加一个具体类,一般也要相应地增加一个factory类,增加了系统复杂度。四、实现(1)AbstractFactory类中通常是一组FactoryMethod的集合。个人认为与FactoryMethod模式没有本质区别。(2)通常可以把工厂作为单件。五、示例代码namespaceDesignPattern_AbstractFactory{classAbstractProductA{};//ProductAclassProductA1:publicAbstractProductA{};classProductA2:publicAbstractProductA{};classAbstractProductB{};//ProductBclassProductB1:publicAbstractProductB{};classProductB2:publicAbstractProductB{};classAbstractFactory{public:virtualAbstractProductA*CreateProductA()=0;//创建ProductAvirtualAbstractProductB*CreateProductB()=0;//创建ProductB};classConcreteFactory1:publicAbstractFactory{public:virtualAbstractProductA*CreateProductA(){returnnewProductA1();}virtualAbstractProductB*CreateProductB(){returnnewProductB1();}staticConcreteFactory1*Instance(){staticConcreteFactory1instance;return&instance;}protected:ConcreteFactory1(){}private:ConcreteFactory1(constConcreteFactory1&);ConcreteFactory1&operator=(constConcreteFactory1&);};classConcreteFactory2:publicAbstractFactory{public:virtualAbstractProductA*CreateProductA(){returnnewProductA2();}virtualAbstractProductB*CreateProductB(){returnnewProductB2();}staticConcreteFactory2*Instance(){staticConcreteFactory2instance;return&instance;}protected:ConcreteFactory2(){}private:ConcreteFactory2(constConcreteFactory2&);ConcreteFactory2&operator=(constConcreteFactory2&);};}客户端代码:{usingnamespaceDesignPattern_AbstractFactory;//第一种创建方法AbstractFactory*pFactory=ConcreteFactory1::Instance();AbstractProductA*pProductA=pFactory->CreateProductA();AbstractProductB*pProductB=pFactory->CreateProductB();//第二种创建方法pFactory=ConcreteFactory2::Instance();pProductA=pFactory->CreateProductA();pProductB=pFactory->CreateProductB();}六、实例最早知道类厂的概念是在COM中,但当时也没想到这是如此重要的一种模式,在许多其他模式中都可以用到类厂模式。COM中不能直接创建组件,这也是由COM的一个特性决定的:即客户不知道要创建的组件的类名。C++设计模式之Singleton2002-07-26····COM集中营一、功能保证一个类仅有一个实例。二、结构图三、优缺点Singleton模式是做为"全局变量"的替代品出现的。所以它具有全局变量的特点:全局可见、贯穿应用程序的整个生命期,它也具有全局变量不具备的性质:同类型的对象实例只可能有一个。四、实现教科书上的Singleton定义如下:classSingleton{public:staticSingleton*Instance();protected:Singleton(){}private:staticSingleton*_instance;Singleton(constSingleton&);Singleton&operator=(constSingleton&);};Singleton*Singleton::_instance=NULL;Singleton*Singleton::Instance(){(_instance==NULL)?_instance=newSingleton():0;//lazyinitializationreturn_instance;}(1)因为返回的是指针,为防止用户调用delete函数,可把staticSingleton*_instance;改为在Instance()中定义staticSingleton_instance。这样显然更安全,同时也具有lazyinitialization的特性(即第一次访问时才创建)。(2)假设需要从Singleton派生子类,而子类也需要有同样的性质,既只能创建一个实例。我觉得,这很难办。根本原因在于Instance()函数不是虚函数,不具有多态的性质。一种常用方法是把Instance()函数移到子类中,这时就只能用staticSingleton*_instance,而不能用staticSingleton_instance了,除非把_instance也要移到子类,无论怎么做都不优雅。另一种方法是用模板。具体用什么方法,只能根据实际情况权衡。五、示例代码(1)没子类的情况namespaceDesignPattern_Singleton{classSingleton{public:staticSingleton*Instance(){staticSingleton_instance;return&_instance;}protected:Singleton(){}private:Singleton(constSingleton&);Singleton&operator=(constSingleton&);};}客户端代码:{usingnamespaceDesignPattern_Singleton;Singleton*p=Singleton::Instance();......}(2)有子类的情况方法一:namespaceDesignPattern_Singleton{//classSingletonclassSingleton{protected:Singleton(){}staticSingleton*_instance;private:Singleton(constSingleton&);Singleton&operator=(constSingleton&);};Singleton*Singleton::_instance=NULL;//classConcreteSingletonclassConcreteSingleton:publicSingleton{public:staticSingleton*Instance();protected:ConcreteSingleton(){}};Singleton*ConcreteSingleton::Instance(){(_instance==NULL)?_instance=newConcreteSingleton():0;return_instance;}}客户端代码:{usingnamespaceDesignPattern_Singleton;Singleton*p=ConcreteSingleton::Instance();}方法二:namespaceDesignPattern_Singleton{//classSingletonclassSingleton{protected:Singleton(){}private:Singleton(constSingleton&);Singleton&operator=(constSingleton&);};//classConcreteSingletonclassConcreteSingleton:publicSingleton{public:staticSingleton*Instance(){staticConcreteSingleton_instance;return&_instance;}protected:ConcreteSingleton(){}};}客户端代码:{usingnamespaceDesignPattern_Singleton;Singleton*p=ConcreteSingleton::Instance();}方法三:namespaceDesignPattern_Singleton{template<classT>classSingleton{public:staticT*Instance(){staticT_instance;return&_instance;}protected:Singleton(){}private:Singleton(constSingleton&);Singleton&operator=(constSingleton&);};classConcreteSingleton:publicSingleton<ConcreteSingleton>{};}客户端代码{usingnamespaceDesignPattern_Singleton;ConcreteSingleton*p=ConcreteSingleton::Instance();}C++模式开发之Bridge2002-07-29····COM集中营一、功能将抽象部分与它的实现部分分离,使它们都可以独立地变化。二、结构图三、示例代码namespaceDesignPattern_Bridge{//classImplementorclassImplementor{public:virtualvoidOperationImp()=0;};//classConcreteImplementorAclassConcreteImplementorA:publicImplementor{public:virtualvoidOperationImp(){}};//classConcreteImplementorBclassConcreteImplementorB:publicImplementor{public:virtualvoidOperationImp(){}};//classAbstractionclassAbstraction{public:voidOperation(Implementor*imp){assert(imp);imp->OperationImp();}};}客户端代码:{usingnamespaceDesignPattern_Bridge;Abstractionobj;Implementor*impa=newConcreteImplementorA();Implementor*impb=newConcreteImplementorB();obj.Operation(impa);//第一种实现方法obj.Operation(impb);//第二种实现方法}四、实例(1)创建可以在XWindowSystem和IBM的PresentationManager系统中都可以使用的窗口。(书上的例子)Bridge的魅力在于抽象和实现之间是松散的关系,它们之间可以进行随意组合。如上图中,就有IconWindow+XWindowImp、TransientWindow+XWindowImp、IconWindow+PMWindowImp、TransientWindow+PMWindowImp四种组合。C++模式设计之Builder2002-07-30····COM集中营一、功能将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。二、结构图各类之间的交互关系如下图所示:三、示例代码namespaceDesignPattern_Builder{classProduct1{/*...*/};classProduct2{/*...*/};//classBuilderclassBuilder//抽象基类{public:virtualvoidBuilderPartA(){}//提供缺省实现virtualvoidBuilderPartB(){}virtualvoidBuilderPartC(){}protected:Builder(){}};//classConcreteBuilder1classConcreteBuilder1:publicBuilder//创建Product1{public:ConcreteBuilder1():_product(NULL){}virtualvoidBuilderPartA(){/*...*/}virtualvoidBuilderPartB(){/*...*/}virtualvoidBuilderPartC(){/*...*/}virtualProduct1*GetProduct1(){return_product;}//返回创建的Product1对象private:Product1*_product;};//classConcreteBuilder2classConcreteBuilder2:publicBuilder//创建Product2{public:ConcreteBuilder2():_product(NULL){}virtualvoidBuilderPartA(){/*...*/}virtualvoidBuilderPartB(){/*...*/}virtualvoidBuilderPartC(){/*...*/}virtualProduct2*GetProduct2(){return_product;}//返回创建的Product2对象private:Product2*_product;};//classDirectorclassDirector{public://创建对象(Director并不知道具体创建出来的对象是什么样的,只有调用该函数的client知道)voidConstruct(Builder*builder){builder->BuilderPartA();builder->BuilderPartB();builder->BuilderPartC();}};}客户端代码:{usingnamespaceDesignPattern_Builder;Directordirector;//创建第一种对象ConcreteBuilder1*pBuilder1=newConcreteBuilder1();director.Construct(pBuilder1);Product1*product1=pBuilder1->GetProduct1();//创建第二种对象ConcreteBuilder2*pBuilder2=newConcreteBuilder2();director.Construct(pBuilder2);Product2*product2=pBuilder2->GetProduct2();}四、实例(1)例子一。如下图所示:上图的功能是是把一个RTF文件转换为多种正文格式。RTFReader进行语法 分析 定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析 ,然后将所有的token串逐一转换。可见builder就是一步步地把各个部分组装为一个整体。它封闭了组装的方法,组装出来的对象也大相径庭。C++设计模式之Prototype2002-08-01····COM集中营一、功能用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。二、结构图三、优缺点优点:复制自身。客户不知道需要对象的实际类型,只需知道它的抽象基类即可。(即有继承树的情况)缺点:必须先有一个对象实例(即原型)才能clone。四、示例代码namespaceDesignPattern_Prototype{//classPrototypeclassPrototype//抽象基类{public:virtualPrototype*Clone()=0;};//classConcretePrototype1classConcretePrototype1:publicPrototype{public:virtualPrototype*Clone(){ConcretePrototype1*p=newConcretePrototype1();*p=*this;//复制对象returnp;}};//classConcretePrototype2classConcretePrototype2:publicPrototype{public:virtualPrototype*Clone(){ConcretePrototype2*p=newConcretePrototype2();*p=*this;//复制对象returnp;}};}客户端代码:{usingnamespaceDesignPattern_Prototype;ConcretePrototype1*obj1=newConcretePrototype1();//原型对象1ConcretePrototype2*obj2=newConcretePrototype2();//原型对象2Prototype*newobj1=obj1->Clone();//克隆对象1Prototype*newobj2=obj2->Clone();//克隆对象2//使用复制出的对象newobj1和newobj2}
本文档为【c++设计模式(精简版)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_701996
暂无简介~
格式:pdf
大小:277KB
软件:PDF阅读器
页数:22
分类:互联网
上传时间:2012-11-03
浏览量:73