C++设计模式.docx
- 文档编号:8458824
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:147
- 大小:456.58KB
C++设计模式.docx
《C++设计模式.docx》由会员分享,可在线阅读,更多相关《C++设计模式.docx(147页珍藏版)》请在冰豆网上搜索。
C++设计模式
设计模式C++学习笔记之一(Strategy策略模式)
无意中,从网上下到一本电子书《24种设计模式介绍与6大设计原则》,很好奇这里有24种设计模式,印象中GOF写的《设计模式》(DesignPatterns),好像只有23种吧。
运行起来一看,还真挺吸引咱的,里面提到的例子都很有趣。
很感谢作者写出这样好的例子来,我的目的是把作者提到的例子用C++来实现。
写这本书的作者是:
cbf4life,更详细的内容及说明可以参考原作者博客:
。
这里只进行简单提示和实现编码。
1.1.解释
main(),赵云
CContext,锦囊
IStrategy,策略接口
CBackDoor,策略之一
CGivenGreenLight,策略之二
CBlockEnemy,策略之三
说明:
一个策略放到一个锦囊里。
当用的时候,找到这个锦囊,从锦囊里拿出策略来使用。
注意:
锦囊只是简单的装载和调用策略,锦囊里没有逻辑。
策略会有更大的自主权,运行更多的逻辑。
看代码:
classIStrategy
{
public:
IStrategy(void);
virtual~IStrategy(void);
virtualvoidOperate(void)=0;
};
classCBackDoor:
publicIStrategy
{
public:
CBackDoor(void)
{
}
~CBackDoor(void)
{
}
voidOperate(void)
{
cout<<"找乔国老帮忙让吴国太给孙权施加压力"< } }; classCGivenGreenLight: publicIStrategy { public: CGivenGreenLight(void) { } ~CGivenGreenLight(void) { } voidOperate(void) { cout<<"求吴国太开个绿灯,放行! "< } }; classCBlockEnemy: publicIStrategy { public: CBlockEnemy(void) { } ~CBlockEnemy(void) { } voidOperate() { cout<<"孙夫人断后,挡住追兵! "< } }; classCContext { public: CContext(IStrategy*pStrategy) { this->m_pStrategy=pStrategy; } ~CContext(void) { deletethis->m_pStrategy; } voidOperate(void) { this->m_pStrategy->Operate(); } private: IStrategy*m_pStrategy; }; int_tmain(intargc,_TCHAR*argv[]) { CContext*pContext; cout<<"---------刚刚到吴国的时候拆第一个----------"< pContext=newCContext(newCBackDoor()); pContext->Operate(); deletepContext; cout<<"\n\n-----刘备乐不思蜀了,拆第二个了------"< pContext=newCContext(newCGivenGreenLight()); pContext->Operate(); deletepContext; cout<<"\n\n-----孙权的小兵追了,咋办拆第三个------"< pContext=newCContext(newCBlockEnemy()); pContext->Operate(); deletepContext; return0; } 一个锦囊只能装一个妙计,赵云可以有多个锦囊。 属于对象行为型模式。 很简单的一个模式了,貌似这24个里面,这是最简单的了。 也好,先用一个简单容易的开头,都说万事开头难,找个简单的开始,鼓励自己坚持学下来,就会有收获。 博客也会起到这个作用吧,鼓励自己。 上图不是单纯的抽象出来的模式类图,而只是描述了代码里用到的类之间的关系图。 真正的抽象类图,只有策略接口和一个策略实现类,还有CContext类以及Client。 设计模式C++学习笔记之二(Proxy代理模式) 代理,一看名字就知道这只是个中介而已,真实的执行者在代理的后面呢。 cbf4life在他的书里提的例子也很有趣,更详细的内容及说明可以参考原作者博客: 。 现在贴代码,以方便随用随取。 2.1.解释 main(),西门庆 IKindWomen,接口 CWangPo,代理 CPanJinLian,实际执行者之一 CJiaShi,实际执行者之二 说明: 代理和实际执行者派生于共同的接口,代理拥有实际执行者的实例。 代理的每一个函数(接口的实现函数),直接调用实际执行者的对应接口函数。 注意: 代理只是简单的装载,然后调用实际执行者的函数。 看代码: classIKindWomen { public: IKindWomen(void); virtual~IKindWomen(void); virtualvoidMakeEyesWithMan()=0; virtualvoidHappyWithMan()=0; }; classCWangPo: publicIKindWomen { public: CWangPo(IKindWomen*pKindWomen) { this->m_pKindWomen=pKindWomen; } ~CWangPo(void) { deletethis->m_pKindWomen; } voidHappyWithMan() { this->m_pKindWomen->HappyWithMan(); } voidMakeEyesWithMan(void) { this->m_pKindWomen->MakeEyesWithMan(); } private: IKindWomen*m_pKindWomen; }; classCPanJinLian: publicIKindWomen { public: CPanJinLian(void) { } ~CPanJinLian(void) { } voidHappyWithMan(void) { cout<<"潘? 金e莲¢? 和¨ª男D人¨? 做Á? 那? 个? ......"< } voidMakeEyesWithMan(void) { cout<<"潘? 金e莲¢? 抛¡Á媚? 眼? "< } }; classCJiaShi: publicIKindWomen { public: CJiaShi(void) {} ~CJiaShi(void) {} voidHappyWithMan(void) { cout<<"贾? 氏º? 和¨ª男D人¨? 做Á? 那? 个? ......"< } voidMakeEyesWithMan(void) { cout<<"贾? 氏º? 抛¡Á媚? 眼? "< } }; int_tmain(intargc,_TCHAR*argv[]) { CWangPo*pWangPo; //西¡Â门? 庆¨¬想? 找¨°潘? 金e莲¢? ,ê? 让¨? 王ª? 婆? 来¤¡ä安ã2排? 。 ¡ê pWangPo=newCWangPo(newCPanJinLian()); pWangPo->MakeEyesWithMan(); pWangPo->HappyWithMan(); deletepWangPo; //西¡Â门? 庆¨¬想? 找¨°贾? 氏º? ,ê? 让¨? 王ª? 婆? 来¤¡ä安ã2排? 。 ¡ê pWangPo=newCWangPo(newCJiaShi()); pWangPo->MakeEyesWithMan(); pWangPo->HappyWithMan(); deletepWangPo; return0; } 看起来代理模式的结构和策略模式类似,都是由一个类来装载接口的一个实例,策略模式是CContext来装载,代理模式是CWangPo来装载。 CContext不是从IStrategy派生,所以不需要实现IStrategy接口函数,而CWangPo是从IKindWomen派生的所以CWangPo很清楚CPanJinLian和CJiaShi的接口函数。 这就是代理,代理人知道被代理人能干的事情即函数,所以代理人可以成为中介。 代理模式可以很好的将前后端分开,实现了松散耦合。 代理模式属于结构型模式。 上图仍然是例子中用到的类相关图,并不是代理模式的抽象类图。 这样的类图更容易理解代理模式。 抽象类图当然具有更高的抽象层次,但不利于理解。 设计模式C++学习笔记之三(Singleton单例模式) 单例模式看起来也蛮简单的,就是在系统中只允许产生这个类的一个实例,既然这么简单,就直接贴代码了。 更详细的内容及说明可以参考原作者博客: 。 3.1.解释 main(),大臣 CEmperor,需要单例的类 说明: 很多大臣拜见的皇帝,只有一个。 体现在面向对象方面,CEmperor定义一个静态指针,和一个静态函数,私有化构造函数、析构函数、构造函数复制、重载赋值语句。 注意: 线程安全,采用互斥体的方式实现。 看代码: //Emperor.h #pragmaonce #include usingstd: : cout; usingstd: : endl; usingstd: : string; classCEmperor { public: staticCEmperor*GetInstance(); staticvoidReleaseInstance(); voidEmperorInfo(void); voidSetEmperorTag(stringtag); private: CEmperor(void); virtual~CEmperor(void); CEmperor(constCEmperor&); CEmperor&operator=(constCEmperor&); staticCEmperor*m_pEmperor; staticHANDLEm_pMutex; stringm_EmperorTag; classCGarbo { public: CGarbo() { cout<<"CreateGarbo"< } ~CGarbo() { cout<<"DestroyGarbo"< if(NULL! =m_pEmperor) { WaitForSingleObject(m_pMutex,INFINITE); if(NULL! =m_pEmperor) { cout<<"Removeinstance"< deletem_pEmperor; m_pEmperor=NULL; } ReleaseMutex(m_pMutex); } if(NULL! =m_pMutex) { cout<<"Deletemutex"< CloseHandle(m_pMutex); m_pMutex=NULL; } } }; staticCGarbom_Garbo; }; //Emperor.cpp #include"StdAfx.h" #include"Emperor.h" #include usingstd: : cout; usingstd: : endl; usingstd: : string; CEmperor*CEmperor: : m_pEmperor=NULL; HANDLECEmperor: : m_pMutex=CreateMutex(NULL,FALSE,NULL); CEmperor: : CGarboCEmperor: : m_Garbo; CEmperor: : CEmperor(void) { cout<<"CreateCEmperorInstance"< } CEmperor: : ~CEmperor(void) { cout<<"DestroyCEmperorInstanceandreleaseitsresource"< } voidCEmperor: : EmperorInfo(void) { charmsgBuffer[50]={0}; sprintf_s(msgBuffer,50,"皇¨ºê§o帝Ì? ? 某33某33某33......(%s).",m_EmperorTag.c_str()); stringmsg(msgBuffer); cout< } CEmperor*CEmperor: : GetInstance() { if(NULL==m_pEmperor) { WaitForSingleObject(m_pMutex,INFINITE); if(NULL==m_pEmperor) m_pEmperor=newCEmperor(); ReleaseMutex(m_pMutex); } returnm_pEmperor; } voidCEmperor: : ReleaseInstance() { if(NULL! =m_pEmperor) { WaitForSingleObject(m_pMutex,INFINITE); if(NULL! =m_pEmperor) { deletem_pEmperor; m_pEmperor=NULL; } ReleaseMutex(m_pMutex); } } voidCEmperor: : SetEmperorTag(stringtag) { m_EmperorTag=tag; } //Singleton.cpp #include"stdafx.h" #include"Emperor.h" voidDoIt() { CEmperor*pEmperor1=CEmperor: : GetInstance(); pEmperor1->SetEmperorTag("95"); pEmperor1->EmperorInfo(); CEmperor*pEmperor2=CEmperor: : GetInstance(); pEmperor2->EmperorInfo(); CEmperor*pEmperor3=CEmperor: : GetInstance(); pEmperor3->EmperorInfo(); CEmperor*pEmperor4=pEmperor3; pEmperor4->EmperorInfo(); CEmperor*pEmperor5=NULL; pEmperor5=pEmperor4; pEmperor5->EmperorInfo(); CEmperor: : ReleaseInstance(); } int_tmain(intargc,_TCHAR*argv[]) { DoIt(); _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF); _CrtDumpMemoryLeaks(); return0; } 单例模式比较简单,但在项目中使用的时候,需要明确只调用CEmperor的GetInstance函数来获取实例。 在C#里 有更简单的方法,那就是声明只读的静态变量,比C++简单多了。 但C++更吸引人们去研究,这就是软件研发的乐趣吧。 设计模式C++学习笔记之四(Multition多例模式) 多例模式,这个在GOF的模式设计里没有提到,但在实际工作中确实会用到。 更详细的内容及说明可以参考原作者博客: 。 4.1.解释 main(),客户 略 说明: 和单例基本一样,是有个数限制的单例。 如果对于产生的实例个数没有限制,那就不是多例了,和普通的类没有区别。 举例: 曾经开发过一个从服务端以UDP协议,发送文件到客户端的程序。 客户端连接服务端时采用TCP协议,服务端接受连接,产生一个向客户端传输文件的实例FileService。 每个客户端的连接都会产生一个实例,但同一客户端的多个连接请求会共享一个FileService实例。 理论上讲FileService实例的个数,取决于连接到服务的客户端个数。 由于是企业内部系统,所以这里的个数是有限的,并不在广域网上无限用户的连接。 我想这就是多例模式了,特殊的单例。 可以将实例保存在std: : map里面,用客户端IP和Port组织起来的字符串做为键值。 类图略过。 设计模式C++学习笔记之五(FactoryMethod工厂方法模式) 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。 核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。 这个例子更详细的内容及说明可以参考原作者博客: 。 贴代码了。 5.1.解释 main(),女娲 IHuman,产品接口 CYellowHuman,产品之一 CWhiteHuman,产品之二 CBlackHuman,产品之三 IHumanFactory,工厂接口 CYellowHumanFactory,工厂之一 CWhiteHumanFactory,工厂之二 CBlackHumanFactory,工厂之三 看代码: classIHuman { public: IHuman(void) { } virtual~IHuman(void) { } virtualvoidLaugh()=0; virtualvoidCry()=0; virtualvoidTalk()=0; }; classCYellowHumanpublicIHuman { public: CYellowHuman(void) { } ~CYellowHuman(void) { } voidCry() { cout<<"黄? 色¦? 人¨? 种? 会¨¢哭T"< } voidLaugh() { cout<<"黄? 色¦? 人¨? 种? 会¨¢大䨮笑|,ê? 幸¨°福¡ê呀? ! ê? "< } voidTalk() { cout<<"黄? 色¦人¨种? 会¨说¦话¡ã,一°般ã? 说¦Ì的Ì? 都? 是º? 双? 字Á? 节¨²"< } }; classCWhiteHuman: publicIHuman { public: CWhiteHuman(void) { } ~CWhiteHuman(void) { } voidCry() { cout<<"白ã¡Á色¦? 人¨? 种? 会¨¢哭T"< } voidLaugh() { cout<<"白ã¡Á色¦? 人¨? 种? 会¨¢大䨮笑|,ê? 侵? 略? 的Ì? 笑|声¦¨´"< } voidTalk() { cout<<"白ã¡Á色¦? 人¨? 种? 会¨¢说¦Ì话¡ã,ê? 一°? 般ã? 都? 是º? 单Ì£¤字Á? 节¨²"< } }; classCBlackHuman: publicIHuman { public: CBlackHuman(void) { } ~CBlackHuman(void) { } voidCry() { cout<<"黑¨²人¨? 会¨¢哭T"< } voidLaugh() { cout<<"黑¨²人¨? 会¨¢笑|"< } voidTalk() { cout<<"黑¨²人¨? 可¨¦以°? 说¦Ì话¡ã,ê? 一°? 般ã? 人¨? 听¬y不? 懂? "< } }; classIHumanFactory { public: IHumanFactory(void) { } virtual~IHumanFactory(void) { } virtualIHuman*CreateHuman()=0; }; classCYellowHumanFactory: publicIHumanFactory { public: CYellowHumanFactory(void) { } ~CYellowHumanFactory(void) { } IHuman*CreateHuman(void) { returnnewCYellowHuman(); } }; classCWhiteHumanFactory: publicIHumanFactory { public: CWhiteHumanFactory(void) { } ~CWhiteHumanFactory(void) { } IHuman*CreateHuman(void)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 设计 模式