组件库
谈到COM中的组件,其实用积木来形容它再恰当不过。我们小时候玩积木时,头脑中总是想着各种各样的东西,然后就用块状的积木一块一块地将它们垒起来。我们也可以把组件看成是一块一块的积木,或是一个一个的小单元,这些小单元成为应用程序的各个独立部分
传统应用程序的组成部分是分立的文件、模块或类,这些组成部分经过编译并链接之后才形成应用程序。要想推出应用程序的新版本,就需要将这些组成部分重新编译,既费时又费力。有了组件的概念,就可以将改进后的新组件插入到应用程序中,并替换掉原有的旧组件,从而赋予应用程序新的活力。
另外,由此也可以有这样的想法:把许多已经做好的组件放到一起来形成一个组件库,好比一个类库。当制作应用程序时,如果要用到不同的组件,只需从刚建好的组件库中调出所需要的组件,然后将它们插入到适当的位置,来获得所向往的功能。就像搭积木一样,可以从包装盒中拿出你喜欢的积木单元,扔掉不喜欢的积木单元,然后用智慧修建出属于自己的公寓。
对于组件,我们已经知道了关于它的“块”概念,使用组件的优点在于可以动态地将它们插入或卸出应用程序,这给应用程序制作者带来了很大的方便。但是,实现这些功能却需要一定的基础。一般需要两个条件:第一,组件必须动态链接;第二,各个组件必须隐藏(或封装)其内部的实现细节。
正如上面我们曾讨论过的,组件能够动态地被调用或释放,即我们的最终目的是使得用户在应用程序的运行过程中能动态地使用组件。为了达到这样一个目的,必须要求能够将组件动态地链接到一起。所谓动态,也就是说不是在发布应用程序的时候就把组件同应用程序捆绑在一起,那样也就没有我们现在讨论COM的必要,而是组件同应用表面上处于分离的位置,只有当应用程序运行的时候,组件和应用程序才有机地结合到一起。
下面我们来谈一下封装性。
我们知道应用程序和组件在工作时是处于动态链接状态的。当我们将某个组件用新的组件替换掉时,必须将此组件同系统断开,然后连入一个新的组件。显然,新的组件必须按照与原来的组件相同的方式连接到应用程序中,否则就需要重新编译应用程序,因为应用程序可能根本不认识新的组件,不知道从哪里入手。这时我们就需要“封装性’’。
为了说明得明确些,我们先介绍一些术语。首先谈一下客户。当一个程序或组件使用了其他组件时,我们就称之为客户。客户与其他组件通过接口进行连接,
当某个组件被新的组件替换掉后,或者某个组件发生了变化时,如果连接客户与组件的接口没有任何变化,那么原来的客户就不需要进行任何修改。同样,如果客户有了变动,而接口没有变化,那么组件也就不需要改变。由此,我们可以看到,只要接口保持不变,组件和客户就可以像一个个黑匣子一样移过来移过去。
为了充分发挥动态链接的功能,组件及客户都应该尽可能地不要改变它们的接口,这就意味着它们必须被封装起来。封装类似于将它们都做成黑匣子,组件及客户的内容实现细节不能反映到接口中。接口同内部实现细节的隔离程度越高,组件或客户发生变化时对接口的影响将越小。如此可以看出,在接口没有发生任何变化时,对组件的修改将几乎不会对应用程序的其他部分产生任何影响。
这种封装性的要求对组件也额外地加上了一些限制。
(1)必须将实现组件的编程语言隐藏起来。
使用组件的客户没有那么神通广大,以至于知道自己正在使用的组件到底是用C编写的,还是用Java编写的。而任一客户都应能够使用任一组件,不论它们是用什么编程语言编写的。组件应该没有针对编程语言之说。
世界上正有许多人在用不同的编程语言实现自己的组件,假如某个应用只能使用由C++语言编写的组件,因为C++语言现在比较流行。但是如果某段时间后,有另外一种编程语言流行起来,从而导致人们纷纷放弃使用C++,转而使用另一种编程语言。如此就导致原有的应用程序将不能使用新的组件,而且出现了不同的编写组件的方法。如果某个应用程序可以使用任意一种编程语言编写的组件,那么它的生命力之强就可想而知了。
(2)组件必须以二进制的形式发布。
正如第1点所说,要想隐藏组件的编程语言,组件的发布形式只能是最一般的“世人皆知”的二进制形式,即组件在发布时必须已被编译、链接并且马上就可以投入使用,这也给组件的更新换代提供了很大的便利。
(3)组件不能因为自己所处位置的不同而不断改变自己的形式。
这一点主要是针对网络来说的。组件和使用它的应用程序不仅能够在同一个进程或不同的进程中运行,而且还能在不同的机器上运行。客户对本地组件的访问及使用方式同客户对远程组件的访问及使用方式应该是完全一致的。要不然,当远程组件上某个地方的一个组件拿到本地时,就必须重新编译客户,以便使之能够处理新来的组件。
(4)组件版本的兼容性。
对于新版本的组件应该有向下兼容的特性。客户既能够使用老版本的组件,也能够使用新版本的组件。对于使用者来说,这无疑又是一个很大的便利,而且软件只有朝这个方向发展才能获得顽强的生命力。
组件库
在前面部分,我们已经谈过COM是一个说明如何建立可动态交替更新的组件的规范,它提供了为保证能够互操作而在客户和组件之间应该遵循的标准。但是如果只给出一套规范,而不给出一些具体的实现方式,那么人们还是无从入手。因此COM提供了一个称做COM库(COM library)的API,它为所有客户及组件提供非常有用的组件管理服务。COM提供的操作可以使得对组件的管理都以一致的方式进行,这大大节省了COM编写人员花在组件及客户实现上的时间。另外,对于DCOM,COM库则提供了一些同网络上其他组件通信所需的代码,这不但可以节省开发人员花在网络编程上的时间,而且可以使他们无需了解网络编程的细节知识。
但是我们仍旧要认清另外一点,COM并不是一种计算机语言,COM是由某种编程语言实现的组件编写规范。此外,COM也不是DLL,COM是利用DLL来给组件提供动态链接的能力。