什么是COM
COM是Microsoft组件对象模型(Component Object Model)的简称。
COM是一个说明如何建立可动态交替更新组件的规范。它提供了客户和组件为保证能够互操作应该遵循的标准。该标准对于组件架构的重要性同其他任何一个具有可交替更新部分的系统是一样的。举个例子,如果没有国家标准(GB),那么各个厂家所生产的零件及产品将不能实现互换性。各个厂家各自为政,若电机上的螺栓坏了,就要买原来厂家生产的螺栓,相当不方便。我们所熟悉的超文本格式语言(HTML),实际上也是一种趋向于标准化的语言。没有标准,任何东西都将不能一起工作。
COM规范就是一套为组件架构设置标准的文档。本书中所开发的所有组件都将遵循这一标准。
那么,什么是COM组件呢?
3.1.2 COM组件
COM组件由以Win 32动态连接库(DLL)或可执行文件(EXE)形式发布的可执行代码所组成。遵循COM规范编写出来的组件将能够满足对组件架构的所有要求。
那么,COM组件有什么好处呢?它到底是什么东西呢?这就涉及到作者向大家介绍COM的目的。
3.1.3 为什么要介绍COM
作为传统软件的应用程序在发行之后,使用者要想省略掉其中的某些内容,或者感觉应用程序的某些部分还不够完善,希望得到更好的版本,只有等到软件发行商将新版本重新全部编译并推出后,使用者的这一梦想才能实现。这是传统软件的典型发行方式。但是,这却严重妨碍了软件使用人员的工作效率,使得使用者想做某件事,而软件却没有相应的实现部分。这使得软件的使用范围大幅度缩小,同时也使得商家频于软件升级方面的应酬,而实际上应用程序的开发进度却丝毫得不到加快。
但是,自从COM出现以后,以上问题就基本上迎刃而解了。
有了COM,软件开发人员就可以在应用程序发行后仍可以对它进行修改或给它加上一些新的特性,这大大方便了使用者,因为应用程序能够在更高的程度上被定制,使应用更加灵活、更具动态性。于是,将可能出现这样的情况:每个使用者都在使用相同的软件,而实际上每个使用者的软件却大相径庭。软件开发人员可以用逐步添加的方式开发程序,而不是每隔一两年将其完全重写一遍,这又在很大程度上加快了应用程序的开发进度。
COM被认为是未来应用程序开发的趋势。为此,作者也想尽快将这样一把具有如此好处的“金钥匙”奉献给读者。
3.1.4 COM的历史
COM的前身是OLE,它是对象链接及嵌入的Microsoft版本。OLE的第一个版本使用动态数据交换(DDE)作为客户及组件之间的通信方式。OLE 1中并没有引入COM。但是DDE非常缓慢,而且效率也不高。OLE的第二个版本使用了COM。但OLE是开发出来的第一个COM系统,不能很好地实现COM的功能,这使OLE显得比较庞大且使用不便。现今,COM在很多方面体现了越来越强劲的生命力。
3.1.5 你应有所准备虽然COM是开发软件组件的一种方法,但是组件实际上却是一些小的二进制可执行程序。为此,学习COM首先要有一定的编程基础。虽然COM本身与编程没有关系,但是开发人员总要选择一种编程语言来实现所需的组件。实际上,大家可以有多种选择的余地。可以是C,Java,BASIC,也可以是PYTHON。但是由于大多数组件是用COM编写的,而且这种状况还会继续下去,因此本书所给出的示例代码均为C++代码。
组件的特点
谈到COM中的组件,其实用积木来形容它再恰当不过。我们小时候玩积木时,头脑中总是想着各种各样的东西,然后就用块状的积木一块一块地将它们垒起来。我们也可以把组件看成是一块一块的积木,或是一个一个的小单元,这些小单元成为应用程序的各个独立部分
传统应用程序的组成部分是分立的文件、模块或类,这些组成部分经过编译并链接之后才形成应用程序。要想推出应用程序的新版本,就需要将这些组成部分重新编译,既费时又费力。有了组件的概念,就可以将改进后的新组件插入到应用程序中,并替换掉原有的旧组件,从而赋予应用程序新的活力。
另外,由此也可以有这样的想法:把许多已经做好的组件放到一起来形成一个组件库,好比一个类库。当制作应用程序时,如果要用到不同的组件,只需从刚建好的组件库中调出所需要的组件,然后将它们插入到适当的位置,来获得所向往的功能。就像搭积木一样,可以从包装盒中拿出你喜欢的积木单元,扔掉不喜欢的积木单元,然后用智慧修建出属于自己的公寓。
对于组件,我们已经知道了关于它的“块”概念,使用组件的优点在于可以动态地将它们插入或卸出应用程序,这给应用程序制作者带来了很大的方便。但是,实现这些功能却需要一定的基础。一般需要两个条件:第一,组件必须动态链接;第二,各个组件必须隐藏(或封装)其内部的实现细节。
正如上面我们曾讨论过的,组件能够动态地被调用或释放,即我们的最终目的是使得用户在应用程序的运行过程中能动态地使用组件。为了达到这样一个目的,必须要求能够将组件动态地链接到一起。所谓动态,也就是说不是在发布应用程序的时候就把组件同应用程序捆绑在一起,那样也就没有我们现在讨论COM的必要,而是组件同应用表面上处于分离的位置,只有当应用程序运行的时候,组件和应用程序才有机地结合到一起。
下面我们来谈一下封装性。
我们知道应用程序和组件在工作时是处于动态链接状态的。当我们将某个组件用新的组件替换掉时,必须将此组件同系统断开,然后连入一个新的组件。显然,新的组件必须按照与原来的组件相同的方式连接到应用程序中,否则就需要重新编译应用程序,因为应用程序可能根本不认识新的组件,不知道从哪里入手。这时我们就需要“封装性’’。
为了说明得明确些,我们先介绍一些术语。首先谈一下客户。当一个程序或组件使用了其他组件时,我们就称之为客户。客户与其他组件通过接口进行连接,
当某个组件被新的组件替换掉后,或者某个组件发生了变化时,如果连接客户与组件的接口没有任何变化,那么原来的客户就不需要进行任何修改。同样,如果客户有了变动,而接口没有变化,那么组件也就不需要改变。由此,我们可以看到,只要接口保持不变,组件和客户就可以像一个个黑匣子一样移过来移过去。
为了充分发挥动态链接的功能,组件及客户都应该尽可能地不要改变它们的接口,这就意味着它们必须被封装起来。封装类似于将它们都做成黑匣子,组件及客户的内容实现细节不能反映到接口中。接口同内部实现细节的隔离程度越高,组件或客户发生变化时对接口的影响将越小。如此可以看出,在接口没有发生任何变化时,对组件的修改将几乎不会对应用程序的其他部分产生任何影响。
这种封装性的要求对组件也额外地加上了一些限制。
(1)必须将实现组件的编程语言隐藏起来。
使用组件的客户没有那么神通广大,以至于知道自己正在使用的组件到底是用C编写的,还是用Java编写的。而任一客户都应能够使用任一组件,不论它们是用什么编程语言编写的。组件应该没有针对编程语言之说。
世界上正有许多人在用不同的编程语言实现自己的组件,假如某个应用只能使用由C++语言编写的组件,因为C++语言现在比较流行。但是如果某段时间后,有另外一种编程语言流行起来,从而导致人们纷纷放弃使用C++,转而使用另一种编程语言。如此就导致原有的应用程序将不能使用新的组件,而且出现了不同的编写组件的方法。如果某个应用程序可以使用任意一种编程语言编写的组件,那么它的生命力之强就可想而知了。
(2)组件必须以二进制的形式发布。
正如第1点所说,要想隐藏组件的编程语言,组件的发布形式只能是最一般的“世人皆知”的二进制形式,即组件在发布时必须已被编译、链接并且马上就可以投入使用,这也给组件的更新换代提供了很大的便利。
(3)组件不能因为自己所处位置的不同而不断改变自己的形式。
这一点主要是针对网络来说的。组件和使用它的应用程序不仅能够在同一个进程或不同的进程中运行,而且还能在不同的机器上运行。客户对本地组件的访问及使用方式同客户对远程组件的访问及使用方式应该是完全一致的。要不然,当远程组件上某个地方的一个组件拿到本地时,就必须重新编译客户,以便使之能够处理新来的组件。
(4)组件版本的兼容性。
对于新版本的组件应该有向下兼容的特性。客户既能够使用老版本的组件,也能够使用新版本的组件。对于使用者来说,这无疑又是一个很大的便利,而且软件只有朝这个方向发展才能获得顽强的生命力。
3.2.2 组件库
在前面部分,我们已经谈过COM是一个说明如何建立可动态交替更新的组件的规范,它提供了为保证能够互操作而在客户和组件之间应该遵循的标准。但是如果只给出一套规范,而不给出一些具体的实现方式,那么人们还是无从入手。因此COM提供了一个称做COM库(COM library)的API,它为所有客户及组件提供非常有用的组件管理服务。COM提供的操作可以使得对组件的管理都以一致的方式进行,这大大节省了COM编写人员花在组件及客户实现上的时间。另外,对于DCOM,COM库则提供了一些同网络上其他组件通信所需的代码,这不但可以节省开发人员花在网络编程上的时间,而且可以使他们无需了解网络编程的细节知识。
但是我们仍旧要认清另外一点,COM并不是一种计算机语言,COM是由某种编程语言实现的组件编写规范。此外,COM也不是DLL,COM是利用DLL来给组件提供动态链接的能力。
ATL,Active Template Library活动模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。 待了解下