MFC,STL,COM,ATL中使用了哪些设计模式?

时间:2020-12-19 23:15:46
近日,偶读"设计模式"一书
虽不能完全理解,但已获益不少。
OOP编程思想,可谓博大精深,在学习及使用VC时,除了需要对常规的封装、继承、多态的理解外,还要加上对多种设计模式的理解与灵活运用才能充发挥VC++面向对象编程的强大潜力。

实际上,设计模式并不遥远,各位多多少少在自己的编程实践中使用过,高手们,可能不需要看这方面的书,也能一一总结出来。

MFC本身就是一个集合了多种设计模式的Framework。平常在使用MFC时,实际上就是在一些模式中填空。因此,MFC及其源码就是一个学习OOP和设计模式的极好教材。

我自己琢磨了一下,MFC中有一些使用频率很高的设计模式
如 模板方法 (template Method) 在基类中,将程序流程写好,其中调用了虚函数,由派生类中虚函数的实现来完成具体步骤。(基类定框框,派生类填空)
如CView派生类的OnDraw ,文档类中的OnOpenDocument,OnNewDocument等等。

又如 文档视图结构本身,就可归结为 模型\视图\控制器模式(MVC)将逻辑与表像分理出来了。

此外,STL中,大量使用的iterator(迭代器)也是一种不错的模式。

MFC中使用的设计模式应该很多,远非我现在所能理解的。此外STL,COM,ATL中也都处处有设计模式的影子,如能对这些平时机械使用的东西加以分析,从中学习编程的思想,对于提高自己的编程能力,系统分析能力是会有很大的益处的。

因此,本人高分给出这样一个论题,望大家参与讨论,共同学习。共同提高。

44 个解决方案

#1


听课学习!!!

#2


factory Method 

#3


COM中好像用到了代理(Proxy)模式。

#4


Doc/View模式,数据和显示的分离管理。

#5


我来总结两个:

●Iterator(迭代器)
意图: 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
示例: STL中的Containers与Iterator 
STL中,提供了很多总数据结构,为这些数据结构又定义了很多种统一迭代器,通过迭代器来访问数据结构的元素。这样就将数据的访问与数据的内部存储结构分隔开了,使所有的数据结构有共通的访问方式。

●Template Method(模板方法)
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
示例:
这种模式在MFC源码中被大量使用。
典型的有: CView基类对WM_PANT消息的相应
void CView::OnPaint()
{
//处理流程
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
然后派生类实现OnPrepareDC,OnDraw完成具体的步骤。

#6


听课!

#7


up

#8


各种映射表。

#9


没有人愿意详细的讨论这个问题吗?

#10


又总结出来一种:

●Bridge(桥接)
意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
示例:MFC中的 (Serialization) 序列化机制
在序列化机制中,CArchive 和 CFile共同完成了数据的永久存储
CArchive定义了数据存取的共用接口
而CFile及其派生类 则完成了存储过程的具体实现(文件、内存缓冲区等等)
这样,数据存储的接口部分与具体实现部分被分离了。给CArchive搭配不同的CFile派生类就可实现不同的物理存储。

#11


有些问题自己还没仔细研究过,心思一半去研究人了,其中八成用来研究妹妹
哎!看完这贴手艺极深,回家看书去!

#12


(怎么成了自问自答了????????  这300分怎么没人要???        )

●Observer(观察者)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
示例:MFC 中的文档视图结构
一个文档对象可以对应多个视图对象,视图对象是对文档对象的诠释。
当文档对象发生变化后,调用UpdateAllViews 更新视图
然后各个视图的OnUpdate 被调用。

#13


后两种是我由codeproject上一篇文章中总结的。

另外,我感觉得到doc-view文档结构中 文档模板的定义应该算是一种模式,不过,现在还总结不出是那种。

还有,CObject派生类的动态生成CreateObject也是否是某种模式。

楼上有同志提出了
factory Method(工厂方法) 
Proxy(代理)
两种模式,我还没找到具体的实例。
大家帮忙想想吧。

#14


听课

#15


MFC中消息链的设计可以说是职责链的变体

#16


非常感谢 mountebank(bat)

我来总结一下
●Chain of Responsibility (职责链)
意图:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

示例:
MFC消息链
在MFC中各 CCmdTarget派生类定义自己对特定消息及命令的响应动作。
消息和命令沿着消息映射定义的链进行传递,直到有对象处理他。

另感谢bgsn(不告诉你) 制作了 "设计模式迷你手册.chm "
本文中的 "意图" 字段都是从该chm中拷贝的。
参见: http://www.csdn.net/expert/topic/159/159403.shtm

#17


STL和ATL都有Template Method 和 Iterator。并且Template Method是最大量使用的设计模式。COM和ATL/MFC/STL不是同一回事吧?我觉得只是一种对象模型,如果考虑设计模式最多只能考虑这种模型的设计模式(当然这也很有意义),它和其它的一些库还是不能相提并论的。FMD提出这个问题非常有意义,这应该是另一种较为有效和高层次的学习方法。应该说MFC、STL、ATL都是非常成功的类库,对于学习面向对象的分析与设计特别是设计模式是很好的实例,如果能够深入讨论下去肯定对大家非常有帮助。

#18


看来高手真的不多呀,
竟FMD(Niko)自己回答了
谢谢你,给菜鸟们上了一课

#19


关注

#20


真的受益不少!!谢了。
听了一堂生动的课!!!

#21


研究过"设计模式"的朋友,帮着找找啊!
我将总结出一篇文章,注上各位的大名。

过路的朋友,如果你觉得这篇贴子有价值,就请帮忙推一推。让更多的人参与进来。

#22



赶紧做笔记。

#23


要是用过java,你会发现各种设计模式遍布在jdk的package中,而且名称也是很相似的,也比较容易理解,通过java理解OO和Design Pattern最合适不过了,相比起来,C++的门槛就太高了些。 

#24


好论题,push

#25


MFC的动态对象创建就是一种创建型模式

#26


gz

#27


我推

#28


up@!

#29


看来,没有人愿意补充了,
今晚 24时,给分结贴。

#30


这个问题表面看跟编程没有很大关系,不过,如果能够深刻理解了其工作原理及实现方法,将会在具体实践中获益匪浅呀!很好。

#31


不错

#32


不忙给分嘛,我还想听!!!

#33


单根结构
   
   在面向对象的程序设计中,由于C++的引入而显得尤为突出的一个问题是:
所有类最终是否都应从单独一个基础类继承。在Java中(与其他几乎所有OOP
语言一样),对这个问题的答案都是肯定的,而且这个终级基础类的名字很
简单,就是一个“Object”。这种“单根结构”具有许多方面的优点。单根
结构中的所有对象都有一个通用接口,所以它们最终都属于相同的类型。另
一种方案(就象C++那样)是我们不能保证所有东西都属于相同的基本类型。
从向后兼容的角度看,这一方案可与C模型更好地配合,而且可以认为它的
限制更少一些。但假期我们想进行纯粹的面向对象编程,那么必须构建自己
的结构,以期获得与内建到其他OOP语言里的同样的便利。需添加我们要用到
的各种新类库,还要使用另一些不兼容的接口。理所当然地,这也需要付出
额外的精力使新接口与自己的设计方案配合(可能还需要多重继承)。为得
到C++额外的“灵活性”,付出这样的代价值得吗?当然,如果真的需要——
如果早已是C专家,如果对C有难舍的情结——那么就真的很值得。但假如你
是一名新手,首次接触这类设计,象Java那样的替换方案也许会更省事一些。
单根结构中的所有对象(比如所有Java对象)都可以保证拥有一些特定的功能。
在自己的系统中,我们知道对每个对象都能进行一些基本操作。一个单根结构,
加上所有对象都在内存堆中创建,可以极大简化参数的传递(这在C++里是一个
复杂的概念)。
   
   以上这段见Thinking in Java
   MFC中所有继承自CObject的对象都可以具有一些共同的操作,包括
动态类型识别,动态生成等。所有继承自CCmdTarget的对象都可以对消息
进行处理等。
   在MFC都是利用类似的方法。为了灵活和节约内存,没有采用继承的方法,
而是通过宏在每个类中加入了同样的结构(都放在Public部分),一般最后
都形成一条链。
   如宏 DECLARE_DYNAMIC(class_name)
   就是为类public部分添加了一个CRuntimeClass对象,当然是静态类型。
   我觉得这有些像职责链。然后再加上模板方法,最后实现了MFC对各个请求
的分派和处理。

#34


设计模式贯彻了MFC,JDK,VCL中,可是我还没找到这本书。找到了一定要好好的看!

#35


MFC。

#36


设计模式讲得比较抽象,如果仔细读几遍会有很大收获,它确实是译本好书。

#37


push

#38


我买到《设计模式》了,我觉得JDK中对设计模式的体现最为彻底。比如Java的io设计,体现了修饰器模式,Java的事件,体现了Adapter模式。还有很多

#39


好贴,我推!

#40


案也推一下

#1


听课学习!!!

#2


factory Method 

#3


COM中好像用到了代理(Proxy)模式。

#4


Doc/View模式,数据和显示的分离管理。

#5


我来总结两个:

●Iterator(迭代器)
意图: 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
示例: STL中的Containers与Iterator 
STL中,提供了很多总数据结构,为这些数据结构又定义了很多种统一迭代器,通过迭代器来访问数据结构的元素。这样就将数据的访问与数据的内部存储结构分隔开了,使所有的数据结构有共通的访问方式。

●Template Method(模板方法)
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
示例:
这种模式在MFC源码中被大量使用。
典型的有: CView基类对WM_PANT消息的相应
void CView::OnPaint()
{
//处理流程
CPaintDC dc(this);
OnPrepareDC(&dc);
OnDraw(&dc);
}
然后派生类实现OnPrepareDC,OnDraw完成具体的步骤。

#6


听课!

#7


up

#8


各种映射表。

#9


没有人愿意详细的讨论这个问题吗?

#10


又总结出来一种:

●Bridge(桥接)
意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
示例:MFC中的 (Serialization) 序列化机制
在序列化机制中,CArchive 和 CFile共同完成了数据的永久存储
CArchive定义了数据存取的共用接口
而CFile及其派生类 则完成了存储过程的具体实现(文件、内存缓冲区等等)
这样,数据存储的接口部分与具体实现部分被分离了。给CArchive搭配不同的CFile派生类就可实现不同的物理存储。

#11


有些问题自己还没仔细研究过,心思一半去研究人了,其中八成用来研究妹妹
哎!看完这贴手艺极深,回家看书去!

#12


(怎么成了自问自答了????????  这300分怎么没人要???        )

●Observer(观察者)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
示例:MFC 中的文档视图结构
一个文档对象可以对应多个视图对象,视图对象是对文档对象的诠释。
当文档对象发生变化后,调用UpdateAllViews 更新视图
然后各个视图的OnUpdate 被调用。

#13


后两种是我由codeproject上一篇文章中总结的。

另外,我感觉得到doc-view文档结构中 文档模板的定义应该算是一种模式,不过,现在还总结不出是那种。

还有,CObject派生类的动态生成CreateObject也是否是某种模式。

楼上有同志提出了
factory Method(工厂方法) 
Proxy(代理)
两种模式,我还没找到具体的实例。
大家帮忙想想吧。

#14


听课

#15


MFC中消息链的设计可以说是职责链的变体

#16


非常感谢 mountebank(bat)

我来总结一下
●Chain of Responsibility (职责链)
意图:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

示例:
MFC消息链
在MFC中各 CCmdTarget派生类定义自己对特定消息及命令的响应动作。
消息和命令沿着消息映射定义的链进行传递,直到有对象处理他。

另感谢bgsn(不告诉你) 制作了 "设计模式迷你手册.chm "
本文中的 "意图" 字段都是从该chm中拷贝的。
参见: http://www.csdn.net/expert/topic/159/159403.shtm

#17


STL和ATL都有Template Method 和 Iterator。并且Template Method是最大量使用的设计模式。COM和ATL/MFC/STL不是同一回事吧?我觉得只是一种对象模型,如果考虑设计模式最多只能考虑这种模型的设计模式(当然这也很有意义),它和其它的一些库还是不能相提并论的。FMD提出这个问题非常有意义,这应该是另一种较为有效和高层次的学习方法。应该说MFC、STL、ATL都是非常成功的类库,对于学习面向对象的分析与设计特别是设计模式是很好的实例,如果能够深入讨论下去肯定对大家非常有帮助。

#18


看来高手真的不多呀,
竟FMD(Niko)自己回答了
谢谢你,给菜鸟们上了一课

#19


关注

#20


真的受益不少!!谢了。
听了一堂生动的课!!!

#21


研究过"设计模式"的朋友,帮着找找啊!
我将总结出一篇文章,注上各位的大名。

过路的朋友,如果你觉得这篇贴子有价值,就请帮忙推一推。让更多的人参与进来。

#22



赶紧做笔记。

#23


要是用过java,你会发现各种设计模式遍布在jdk的package中,而且名称也是很相似的,也比较容易理解,通过java理解OO和Design Pattern最合适不过了,相比起来,C++的门槛就太高了些。 

#24


好论题,push

#25


MFC的动态对象创建就是一种创建型模式

#26


gz

#27


我推

#28


up@!

#29


看来,没有人愿意补充了,
今晚 24时,给分结贴。

#30


这个问题表面看跟编程没有很大关系,不过,如果能够深刻理解了其工作原理及实现方法,将会在具体实践中获益匪浅呀!很好。

#31


不错

#32


不忙给分嘛,我还想听!!!

#33


单根结构
   
   在面向对象的程序设计中,由于C++的引入而显得尤为突出的一个问题是:
所有类最终是否都应从单独一个基础类继承。在Java中(与其他几乎所有OOP
语言一样),对这个问题的答案都是肯定的,而且这个终级基础类的名字很
简单,就是一个“Object”。这种“单根结构”具有许多方面的优点。单根
结构中的所有对象都有一个通用接口,所以它们最终都属于相同的类型。另
一种方案(就象C++那样)是我们不能保证所有东西都属于相同的基本类型。
从向后兼容的角度看,这一方案可与C模型更好地配合,而且可以认为它的
限制更少一些。但假期我们想进行纯粹的面向对象编程,那么必须构建自己
的结构,以期获得与内建到其他OOP语言里的同样的便利。需添加我们要用到
的各种新类库,还要使用另一些不兼容的接口。理所当然地,这也需要付出
额外的精力使新接口与自己的设计方案配合(可能还需要多重继承)。为得
到C++额外的“灵活性”,付出这样的代价值得吗?当然,如果真的需要——
如果早已是C专家,如果对C有难舍的情结——那么就真的很值得。但假如你
是一名新手,首次接触这类设计,象Java那样的替换方案也许会更省事一些。
单根结构中的所有对象(比如所有Java对象)都可以保证拥有一些特定的功能。
在自己的系统中,我们知道对每个对象都能进行一些基本操作。一个单根结构,
加上所有对象都在内存堆中创建,可以极大简化参数的传递(这在C++里是一个
复杂的概念)。
   
   以上这段见Thinking in Java
   MFC中所有继承自CObject的对象都可以具有一些共同的操作,包括
动态类型识别,动态生成等。所有继承自CCmdTarget的对象都可以对消息
进行处理等。
   在MFC都是利用类似的方法。为了灵活和节约内存,没有采用继承的方法,
而是通过宏在每个类中加入了同样的结构(都放在Public部分),一般最后
都形成一条链。
   如宏 DECLARE_DYNAMIC(class_name)
   就是为类public部分添加了一个CRuntimeClass对象,当然是静态类型。
   我觉得这有些像职责链。然后再加上模板方法,最后实现了MFC对各个请求
的分派和处理。

#34


设计模式贯彻了MFC,JDK,VCL中,可是我还没找到这本书。找到了一定要好好的看!

#35


MFC。

#36


设计模式讲得比较抽象,如果仔细读几遍会有很大收获,它确实是译本好书。

#37


push

#38


我买到《设计模式》了,我觉得JDK中对设计模式的体现最为彻底。比如Java的io设计,体现了修饰器模式,Java的事件,体现了Adapter模式。还有很多

#39


好贴,我推!

#40


案也推一下