C++设计模式核心板.docx
- 文档编号:9718812
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:20
- 大小:88.20KB
C++设计模式核心板.docx
《C++设计模式核心板.docx》由会员分享,可在线阅读,更多相关《C++设计模式核心板.docx(20页珍藏版)》请在冰豆网上搜索。
C++设计模式核心板
C++设计模式
一、功能
将一个类的接口转换成客户希望的另外一个接口,解决两个已有接口之间不匹配的问题。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
二、结构图
(1)classadapter
(2)objectadapter
三、实现
和其他很多模式一样,学习设计模式的重点是学习每种模式的思想,而不应拘泥于它的某种具体结构图和实现。
因为模式是灵活的,其实现可以是千变万化的,只是所谓万变不离其宗。
在STL中大量运用了Adapter模式,象functionadapter、iteratoradpter,它们与这里说的adapter结构并不一样,但思想是一样的。
具体的介绍可到侯捷网站上找相关文章,他讲得非常好。
四、示例代码
(1)classadapter
namespaceDesignPattern_Adapter
{
//classAdaptee
classAdaptee
{
public:
voidSpecialRequest(){}
};
//classTarget
classTarget
{public:
virtualvoidRequest()=0;
};
//classAdapter
classAdapter:
publicTarget,privateAdaptee
{
public:
virtualvoidRequest(){SpecialRequest();}
};
客户端代码:
{
usingnamespaceDesignPattern_Adapter;
Target*p=newAdapter();
p->Request();//实际上调用的是Adaptee:
:
SpecialRequest()
}
(2)objectadapternamespaceDesignPattern_Adapter
{
//classAdaptee
classAdaptee
{
public:
voidSpecialRequest(){}
};
//classTarget
classTarget
{
public:
virtualvoidRequest()=0;
};
//classAdapter
classAdapter:
publicTarget
{
public:
virtualvoidRequest(){_adaptee.SpecialRequest();}
private:
Adaptee_adaptee;
};
客户端代码:
{
usingnamespaceDesignPattern_Adapter;
Target*p=newAdapter();
p->Request();//实际上调用的是Adaptee:
:
SpecialRequest()
}
六、实例
(1)STL中的ClassAdapter
STL中的AdapterClass包括:
a.stack(对应的adaptee是deque)。
b.queue(对应的adaptee是deque)。
c.priority_queue(对应的adaptee是vector)。
下面是从VC中的
templateclass_Container=deque<_Ty>>
classstack
{//LIFOqueueimplementedwithacontainer
public:
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
{//testifstackisempty
return(c.empty());
}
size_typesize()const
{//testlengthofstack
return(c.size());
}
value_type&top()
{//returnlastelementofmutablestack
return(c.back());
}
constvalue_type&top()const
{//returnlastelementofnonmutablestack
return(c.back());
}
voidpush(constvalue_type&_Val)
{//insertelementatend
c.push_back(_Val);
}
voidpop()
{//eraselastelement
c.pop_back();
}
bool_Eq(conststack<_Ty,_Container>&_Right)const
{//testforstackequality
return(c==_Right.c);
}
bool_Lt(conststack<_Ty,_Container>&_Right)const
{//testifthis<_Rightforstacks
return(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
简化异常安全代码”,原文出自View第5期"。
文章绝对一流,作者给出的代码中也使用了Adaptor模式,也有一定代表性。
我将其问题一般化,概括出以下示例:
问题:
假设有几个已有类,他们有某些共同的行为,但它们彼此间是独立的(没有共同的基类)。
如:
classT1
{
public:
voidProc(){}
};
classT2
{
public:
voidProc(){}
};
//...
如何以统一的方式去调用这些行为呢?
解决方法1:
很自然的会想到用模板,如:
template
voidTest(Tt)
{
t.Proc();
}
的确不错,但这只适用于简单的情况,有时情况是很复杂的,比如我们无法把类型放到模板参数中!
解决方法2:
困难来自于这些类没有共同的基类,所以我们就创造一个基类,然后再Adapt。
//classIAdaptor,抽象基类
classIAdaptor
{
public:
virtualvoidProc()=0;
};
//classAdaptor
template
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;
};
//classAdaptor
template
classAdaptor:
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{};//ProductA
classProductA1:
publicAbstractProductA{};
classProductA2:
publicAbstractProductA{};
classAbstractProductB{};//ProductB
classProductB1:
publicAbstractProductB{};
classProductB2:
publicAbstractProductB{};
classAbstractFactory
{
public:
virtualAbstractProductA*CreateProductA()=0;//创建ProductA
virtualAbstractProductB*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++设计模式之Singleton
一、功能
保证一个类仅有一个实例。
二、结构图
三、优缺点
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;//lazyinitialization
return_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
{
//classSingleton
classSingleton
{
protected:
Singleton(){}
staticSingleton*_instance;
private:
Singleton(constSingleton&);
Singleton&operator=(constSingleton&);
};
Singleton*Singleton:
:
_instance=NULL;
//classConcreteSingleton
classConcreteSingleton:
publicSingleton
{
public:
staticSingleton*Instance();
protected:
ConcreteSingleton(){}
};
Singleton*ConcreteSingleton:
:
Instance()
{
(_instance==NULL)?
_instance=newConcreteSingleton():
0;
return_instance;
}
}
客户端代码:
{
usingnamespaceDesignPattern_Singleton;
Singleton*p=ConcreteSingleton:
:
Instance();
}
方法二:
namespaceDesignPattern_Singleton
{
//classSingleton
classSingleton
{
protected:
Singleton(){}
private:
Singleton(constSingleton&);
Singleton&operator=(constSingleton&);
};
//classConcreteSingleton
classConcreteSingleton:
publicSingleton
{
public:
staticSingleton*Instance(){staticConcreteSingleton_instance;return&_instance;}
protected:
ConcreteSingleton(){}
};
客户端代码:
{
usingnamespaceDesignPattern_Singleton;
Singleton*p=ConcreteSingleton:
:
Instance();
}
方法三:
namespaceDesignPattern_Singleton
{
template
classSingleton
{
public:
staticT*Instance(){staticT_instance;return&_instance;}
protected:
Singleton(){}
private:
Singleton(constSingleton&);
Singleton&operator=(constSingleton&);
};
classConcreteSingleton:
publicSingleton
}
客
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 设计 模式 核心
![提示](https://static.bdocx.com/images/bang_tan.gif)