关于COM和.net的思考

【 某某提到: 】
: 一般说COM复杂,首先是名词太多,其次是基于ATL的实现比较难懂
: 这并不是COM本身复杂,而是C++已经落后于时代了。所以ATL看起来才会像天书一般


虽然对于全新的工程项目,推荐通过.net实现,但是,只要你工作在Windows平台上,必然会遇到和COM相关的技术和机制,无论是大量的legacy的工程和代码,还是作为OS重要功能以及native组件的首选交互形式和接口暴露方式,比如DirectX API,比如一些WMI的API;最有趣的是,即使是.net的核心CLR本身也是一个COM组件,可以通过Host相关接口让native应用来加载,以在当前进程中启动整个CLR的虚拟执行环境或者叫托管执行环境(managed executive environment)。

把握COM有两点很关键,
1)Interface-based design,从设计和编码思路上就是要完全基于接口;
2)VirtualTable-based binary compatibility, 实现上无论何种语言或者机制,只要符合基于虚表的二进制兼容规范,就都可以实施;

COM仅仅是个规范,基于COM的具体技术非常之多,OLE,Automation,Structural storage,ActiveX...汗牛充栋,还有COM+,这个是提供企业级开发必备的一些基础功能和设施,比如,事务管理机制,对象池,安全管理,消息队列...需要指出,目前即便是.net Framework也没有实现COM+所提供这些机制,只是简单的封装了后者。

COM技术中可能有一些比较困难的地方,接口的一致性,对象的聚合和生命周期,套间,跨套间的接口访问,名字对象,等等;这些并不是COM规范人为制造的困难,而是为了设计和提供,可以跨进程和机器边界,跨异构平台(当然必须实现了COM所规定的基础服务),透明化具体对象类型及对象生命周期,便于统一部署和版本管理的组件技术,所必须付出的代价,这个代价从开发人员角度看具体表现为,概念理解的困难以及具体二进制实现的困难;

不过从另一个角度看,COM已经很容易了,
a) COM规范已把要达致这些目标的系统,所必须提供的接口和特性抽象了出来,只不过为了表达这些抽象的概念而新造的术语名词有些陌生和突兀;如果让遇到相似问题的每一个设计和开发人员都自己来做抽象,未必会生成更好的方案;

b) 为了帮助设计和开发人员,人们提供了很多的开发库,以提高COM开发的正确性和效率;最显著的就是MFC中关于COM/OLE的辅助类和函数,以及为了COM而生的ATL;从本质上看,这些类库都是把COM规范中必须实现的,Windows平台本身没有提供,具体设计和开发人员实际实施时会重复实现的,同时又非常容易出错的那部分功能,集中到了这些类库里统一实现,让具体设计和开发人员以代码重用的形式来实现COM规范;

当然人们也意识到了COM这样的一些问题,特别是具体实现时设计和开发人员必须要关注几乎所有的二进制细节,于是.net就诞生了,把这些规范的许多复杂性都封装在了虚拟机里面,把这些目标功能(跨边界、透明性等等)通过一致而又平滑的平台接口和自描述的meta data,以一种让设计和开发人员更易接受的风格开放了出来;

COM的影响是非常广大的,比如XPCOM ,Firefox上的一种插件技术标准,就是根据COM的思想和原则制定的;许多评论说,Firefox的成功是因为它插件是如此的成功,这也算是COM本身所意料不到的贡献之一。

在.net的平台上,即使是.net CLR/SSCLI的具体实现也大量运用了COM的思想和机制,可以说.net就是搭建在COM二进制组件平台之上的虚拟机托管平台。

最后,.net开始时的内部编号是COM 2.0

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

*) 关于“名词太多”
这是要实现可以跨进程和机器边界,跨异构平台(当然必须实现了COM所规定的基础服务),透明化具体对象类型及对象生命周期,便于统一部署和版本管理的组件技术,所必须付出的代价。

COM规范已把要达致这些目标的系统,所必须提供的接口和特性抽象了出来,只不过为了表达这些抽象的概念而新造的术语名词有些陌生和突兀;如果让遇到相似问题的每一个设计和开发人员都自己来做抽象,未必会生成更好的方案;

举个例子,apartment,套间,就是为了抽象传统OS中进程和线程的实现而新造的术语名词和概念;任何人要抽象这样的一些概念,不新造术语,是非常困难的,对比.net,后者用了CLR虚拟机来封装了大多数的实现细节,并用让人更容易接受的风格来开放接口,可事实上仍然新造了一些名词和概念,如类似范畴的AppDomain;

*) 关于“基于ATL的实现比较难懂”
ATL主要使用了template技术,COM接口智能指针,用静态转换来模拟动态绑定,等等,实际并不是很复杂,只能算c++实现机制的中等难度,主要涉及Modern C++ design一书中一些相关设计理念的运用。对比Boost中某些库的实现,ATL很人道了。

*) 关于“这并不是COM本身复杂,而是C++已经落后于时代了”
首先COM的规范的确是复杂的,为啥?第一点已经说了,就是为了要抽象出跨边界和对象透明的组件技术;.net表象上看比较“简单容易”,风格亲近设计和开发人员,实际上复杂事务和实现细节都被划分到CLR那个层面上去实现了;去看一下CLR的开源实现SSCLI,你会发现,整个虚拟机平台的实现,大量运用了COM的思想和机制,就是一个巨型系统平台级的COM server;

其次,COM规范本身是独立于实现语言的,只要构建出的组件符合规范制定的二进制兼容,系统就可以运作,这和C++是否落后时代没有关系。如果开发人员认为,.net才够先进,也完全可以用.net中的托管语言,如C#来实现COM组件;

最后,每种语言都有其适用的范围,现在可以这么说“如果有一个全新的项目需求,要达致跨边界和对象透明组件,并且没有太过严苛的性能需求,那么.net平台及其上的托管语言来实现,比用C++及相关辅助类库来以COM组件形式来实现,要更合适,也更快速便捷和节省预算。”但是,在这个判断上我们加了很多严格的约束,一旦需求变更,特别是项目的非功能性需求,要求高性能运算或者更顺畅的与legacy的native系统相互,那么“使用native语言来实现性能关键以及legacy交互功能,通过COM封装,再由COMInterop交.net托管应用调用”可能是更现实的方案。C++是一门活的语言,不断发展的语言,即使在最新的托管时代里,C#成为标准主流,但C++/CLI仍然是托管语言里功能最完整的语言。

 

posted on 2010-12-19 11:04 flagman 阅读(2021) 评论(5)  编辑 收藏 引用 所属分类: C++COM/COM+.net/CLR

评论

# re: 关于COM和.net的思考 2010-12-19 15:33 溪流

学习了  回复  更多评论   

# re: 关于COM和.net的思考 2010-12-19 18:16 小笨象

C++落后于时代了?.net就不落后了?
抬高一种语言有何意义?
就这种思想,就不是一个好程序员。  回复  更多评论   

# re: 关于COM和.net的思考 2010-12-19 19:29 flagman

@小笨象
您可能理解错了,不同的语言和平台各有各的优缺点,也各有各的用处,要具体情况具体分析;  回复  更多评论   

# re: 关于COM和.net的思考 2010-12-20 11:59 Yotta123

我还在用落后时代的C++呢  回复  更多评论   

# re: 关于COM和.net的思考 2010-12-23 02:16

落后时代这几个字我想不会有人理解错......
楼主你要知道有很多不得不使用C++的地方  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜