荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: qyf (奋起), 信区: Program
标  题: 对目前主流开发技术的分析和总结5(zz)
发信站: 荔园晨风BBS站 (Mon Sep 15 11:11:28 2003), 站内信件

  2.4 COM技术

  COM应当是个更广泛的词汇,其实我觉得Axtive X、OLE、Auto
mation、COM+都应当提及,因为如果你不理解COM,上面的东西你是无法理解的。而且,
我只是想说明COM是一种即将消亡的技术,仅仅说说COM的复杂性和他的问题就够了,
所以不会提及那些东西。为什么会出现COM技术?COM的根本目标是实现代码的对象化
的二进制重用,进而实现软件的?
件化、软件开发工作的分工。这要求他做到两点:第一,能够跨越不同的语言,第二,
要跨越同一种语言的不同编译器。COM技术为这个目标付出了沉重的代价,尤其是为了
跨越不同的编译器,以至于无论对于使用者而言还是开发者而言,他都是一个痛苦的
技术。但幸运的事,这一切终归要结束了。

  让我们从这个目的出发看看COM为什么会成为它现在的样子。其实COM不是什么新玩
意,最初的DLL就是重用二进制代码的技术。DLL在C的年代可能还不错,但到了C++的年
代就不行了。原因在于如果你在.h文件中改变了类定义(增加或者减少了成员变量),
代码库用户的代码必须重新编
译才可以,否则用户的代码会按你的旧类的结构为你的新类分配内存,这将产生什么后
果可想而知。这就是为什么通过接口继承和通过接口操作对象成为COM的强制规范的原
因,能够通过对象的方式组织代码是COM的重要努力。那么著名的IUnknown接口又是怎
么回事呢?这是为了让使用不同编译器的C++开发人员能够共享劳动成果。

  首先看QueryInterface,因为COM是基于接口的,那么一个类可能实现了几个接口,
而对于用户来说,你又只能通过操作接口来操作类,这样你必须把类造型成某个特定
的接口,使用Dynamic_cast吗?不行,因为这是编译器相关的,那么,就只好把它放
在类的实现代码中了,这就是Que
ryInterface的由来。至于AddRef和Release,他们产生的第一个原因是delete这个操
作要求一个类具有虚析构函数(否则的话,他的父类的析构函数将不会被调用),但
不幸的是不同的编译器中析构函数在vtbl中的位置并不相同,这就是说你不能让用户
直接调用delete,那么你的COM对象?
须提供自己删除自己的方法;另外的原因在于一个COM对象可能作为几个接口在被用户
同时使用,如果用户粗暴的删掉了某个接口,那么其他的接口也就不能用了,这样,
只好要求用户在想用一个接口的时候通过AddRef通知COM对象“我要使用你了,你多
了一个用户”,而在不用之后要调用Release告诉COM对象“我不用你了,你少了一
个用户”,如果COM对象发现自己没有用户了,它就把自己删掉。

  再看看诡异的HRESULT,这是跨语言和跨编译器的代价。其实,异常处理是物竞
天择的结果——连一直用效率作标榜的C++都肯牺牲效率来实现这个try-catch,可
见它的意义,但COM为了照顾那些低级的语言居然抛弃了这个特征——产生的结果就
是HRESULT。我们可以看看他是多么愚蠢?
东西。首先,我们要通过一个整数来传递错误信息,通过IErrorInfo来查找真正的
错误描述,本来在现代语言中一个try-catch可以解决的问题,现在我们却需要让用
户和开发者都走很多路才能解决,你怎么评价这个结果?其次,由于这个返回计算
结果的位置被占用了,我们不得不用怪异
的out参数来返回结果。想想一个简单的int add(intop1,intop2)在COM中竟然要变
成HRESULT add(intop1,intop2,int* result),我不知道你对此作何感想。而且由
于COM的方法无法返回一个对象而只能返回一个指针,为了完成一个简单的std::st
ring
GetName()这一类的操作,你要费多少周折——你需要先分配一块内存空间,然后
在COM实现中把一个字符串拷贝到这个空间,用完了你要删掉这个空间,不知道你
是否觉得这种工作很幸福,反正我觉得很痛苦。还有COM为了照顾那些解释性的语
言,又加入了Automation技术,你有没有为此?
得痛苦?本来一个简单的方法调用,现在却需要传给你一个标志变量,然后让你根
据这个标志变量去执行相应的操作。(这一点我现在仍然不明白,为什么解释性的
语言需要通过这个方式来执行一个方法)。“我受够了,我觉得头痛”,你会说,
是啊,我想所有的人都受够了,所有这些因素实际上是把COM技术变成了一头让人
无法驾驭的怪兽。

  人对复杂事物的掌控能力终究是有限的,C++本身已经够复杂了,COM的复杂性
已经超出了我们大部分人的控制能力,你需要忍受种种痛苦得到的东西与你付出的
代价相比是不是太不值得了?我们学习是为了解决问题,而现在我们却需要为了学
习这件事情本身耗费太多的精力。这些痛苦
的东西太多了,我在这里说到的,其实只是一小部分而已。计算机技术是为人类服
务的,而不是少数人的游戏(我想COM技术可能是他的设计者和一部分技术作者的
游戏),难道我们愿意成为计算机的奴隶吗?通过一种过于复杂的技术抛弃所有的
人其实等于被所有的人抛弃,这么多年中选?
J2EE的人我相信不乏高手,你是不是因为COM的过于复杂才选择J2EE的?因为它可
以用简单的途径实现差不多的目标——软件的“二进制”重用、组件化、专业分工
(容器开发商和应用开发商的分工)。事实上,你是被微软所抛弃的,同时,你也
抛弃了微软。

  现在让我们回来吧,我把你带进了COM的迷宫,现在让我把你领回来。再让我们
看看COM到底想实现什么目标,其实很简单,不过是代码的二进制重用,也就是说你
不必给别人源代码,而且你的组件可以象计算机硬件那样“即插即用”。我们回过
头来看看Java,其实,这种二进制重用的
困难是C++所带来的(这不是C++本身的错,而是静态编译的错),当Java出现的时
候,很多问题已经不存在了。你不需要一个头文件,因为Java的字节码是自解释的,
它说明了自己是什么样子的,可以做什么事情。不像C++那样需要一个头文件来解
释这些事情;也不需要事先了解对象的内?
结构,因为内存是在运行的时候才分配的。如果我们现在再回过头来解决COM要解
决的问题,你会怎么做呢?首先你会不再选择C++这种语言来实现代码的“二进制
”重用,其次,你会把所有的语言编译成同样的“二进制”代码(实际上,应当说
是字节码),这显然是更聪明的做法,从前C
OM试图在源代码的级别抹平二进制层次的差异,这实际上是让人在做本来应当由机
器做的事情,很愚蠢是吗?但他们一直做了那么多年,而且把这个痛苦带给了整个
计算机世界——因为他们掌握着事实的标准,为了用户,为了利润,为了能够在
Windows上运行,尽管你知道你在做着一个很不聪明的事情,但你还是做了。

  COM技术为了照顾VB这个小兄弟和实现统一二进制世界的野心,实在浪费了太多
的精力。首先,落后的东西的消亡是必然的,就象C、Pascal在应用领域的消亡一样
,Basic一点一点的改良运动是不符合历史潮流的做法,先进的东西和落后的东西在
一起,要么先进的东西被落后的东西拖?
后腿,要么是同化落后的东西,显然我们更愿意看见后者,现在Basic终于被现代的
计算机语言同化了。其次,统一二进制世界好像不是那么简单的事情,而且也没什
么必要,微软的COM技术奋战了10年,现在也只有他自己和Borland支持,.Net终于
放弃了这个野心。这一切终于要结束了。


  过去J2EE高歌猛进地占领着应用开发的领地,COM在这种进攻面前多少显得苍白
无力。现在微软终于也有了可以和J2EE一较长短的.NET,对于开发人员来讲,基于
字节码的组件的二进制重用现在是天经地义的事情;你不用再为了能够以类方式发
布组件做那么多乱七八糟的事情,因为现?
所有的东西本来就是类了;实现软件开发的分工也很自然,你是专业人员,就用C#
吧,你是应用开发人员,你喜欢用VB.Net,你就用吧,反正你们写的东西最终都被
翻译成了一样的语言(其实我觉得这一点意义不大,因为一些不那么好用的语言被
淘汰是正常的事情,C风格成为程序设计语
言的主流风格,肯定是有它的原因的,语言的统一其实是大势所趋,就象中国人民
都要说普通话一样,我觉得Java不支持多语言算不上缺点——本来就是一种很好看
很好用的语言了,为什么要把简单问题复杂化呢?)。COM不会在短期内死去,因为
我估计微软还不会马上用C#开发Office和W
indows的图形界面部分,但我相信COM技术退出历史舞台的日子已经不远了,作为一
般的开发人员,忘了这段不愉快的历史吧——你将不会在你的世界里直接和COM打交
道。若干年以后,我想COM也许会成为一场笑话,用来讽刺那种野心过大、钻牛角尖
的愚蠢的聪明人。


 --
浪客剑心,此生谁与为伴?

--
※ 修改:·qyf 於 Sep 15 11:16:52 修改本文·[FROM: 192.168.0.182]
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.182]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店