COM组件

前言

COM技术内幕项目源码

编码风格

MFC风格

按MFC风格而写成的。例如在成员变量的前面均加有前缀以m_。这样对于类似于m_SleepBear的变量,读者一看就可知道它是一个成员变量。另外所有类的名称前面均有一个大写的字母CO,例如CCozyBear表示的是类Cozy Bear的名称。下表列出了书中所用的其他一些前缀

前缀含义示例
CCConnectionPoint
I接口IConnectionPoint
m_成员变量BOOL m_bSplleyBear
s_静态成员变量static s_iBear
g_全局变量int g_Bears[100]

匈牙利记法

对于有Windows编程经验的读者,对于匈牙利记法一定不会陌生。匈牙利记法实际上是一套用变量类型来标记变量名称的约定。在本书中作者用了匈牙利记法的一个子集,如表所列。可以看到本书所用的一些记法带有一些任意性,因为它部分是由其他COM、OLE及ActiveX的开发人员所建议的匈牙利记法而得到的。

前缀含义示例
p指针int*pCount;
pl指向接口的指针Ibear*pIBear;
b布尔型BOOL bBear;
i整数int iNumberOfBears;
dwDORDDWORD dwBear;
c计数DWORD cRefs;
sz字符数组char szName[]=“Fuzy”;
wsz宽字符数组wchar_t wszName[]=L"Fuzzy";

组件

组件就是将一整个完整的程序分隔成多个独立的部分,使程序可以更好地不断添加组件以做到不断的更新换代。将单个应用程序(左)分割成多个组件(右),可使之适应各种变化

开发人员应找出一种方法,以能够给已经发行的软件不断地注人新的活力。这
种解决方案就是将单个的应用程序分隔成多个独立的部分,也即组件。
这种作法的好处是可以随着技术的不断发展曲用新的组件取代已有的组件。此时的应用程序将不再像以前那样是一个在发行之前就已命中注定要过时的静态实体,而是可以随着新组件不断取代旧的组件而趋于完善。并且从已有的组件可以建立全新的应用。

COM 即组件对象模型,是建立以及如何通过组件构建应用程序的规范

当然将铁板应用程序拆分成组件需要一个强大的“锤子"。我们所用的“锤子"就被称作是COM。COM,即组件对象模型,是关于如何建立组件以及如何通过组件建构应用程序的一个规范。四年前,Micrxsoft就已经开始开发COM了,其目的是使Micmsoft的各种软件产品更加灵活、更具有动态性并且更易于定制。目前Micmsoft的几乎所有应用程序都使用了COM。Micmsoft的AcitveX技术就是基于COM而建立起来的。

组件优点

应用程序定制

用户可根据自己的需求选择更适合的组件,来将组件架构中的摸个组件替换掉。

用户通常希望能够定制他们所用的应用程序(这一点如同房主总是想根据他们的爱好来定制房间一样),以使应用程序能够按他们自己的工作方式那样工作。在编程人员制方案时,他们需要的是可被修改的应用程序。而组件架构从本质上讲就是可被定制的,因用户可以用更能满足他们需要的组件来将某个组件替换掉。在这里插入图片描述
例如,假定某些组件是基于编辑器ui和Emacs的。在图中,用户1将应用程序配置为使用ui,而用户2更喜欢使用Emacs按照此种方式,可以加入新的组件或改变己有组件而方便地定制应用程序。

组件库

程序员可以应用从组件库中取出所需组件组装以快速构建应用程序,这一梦想随着ActiveX控件的开发成为现实

组件架构最引人注目的优点之一是快速应用程序开发。这一优点可以使开发人员从某个组件库中取出所需的组件并将其快速地组装到一块以构造所需的应用程序,如同积木块一样。在这里插入图片描述
这种从标准的部件构造应用程序的作法,很长时间以来一直是软师们的一个未曾实现的梦想。但是现在这一梦想随在ActiveX控件(以前被称作OLE控件)的开发而正在被变为现实。Visual Basic、C、C++以及Java程序员都可以利ActiveX控件以加速应用程序及Web页面的开发。当然所有的应用程序都不可避免地需要一些特殊的组件,虽然如此,一个应用程序的大部分仍然可以用标准的组件建立起来。

分布式组件

本地只需要创建相应本地组件来转发互联网远地组件的请求,本地程序不需要知道远地组件。

随着网络带宽及其重要性的提高,对由分布在网络上的多个部分组成的应用程序的需求毫无疑问将保持强劲的增长势头。组件架构可以使得开发这类分布式应用的过程得以简化。实际上客户机/服务器式的应用就是向组件架构跨出的第一步。在那里整个应用程序被分成两部分:客户机部分及服务器部分。
在将已有应用程序转化成分布式应用程序时,若已有应用程序是由组件组装成的,那么转化过程将会简单得多。这是因为,首先,应用程序已经被划分成可以位于远地的各外功能部分。其次,由于任一组件均是可以被替换的,由此可以将某个组件替换专门负责同某个远地组件通信的组件。例如在图]巧中,组件C和组件D被放到了网络上远地机器上。在本地,它们被替换成了两个新的组件:Remoting C和Remoting D这两个新的组件的作用是将其他组件发来的请求通过网络转发给Component C和Component D本地机器上的应用程序并不需要知道实际所用到的组件到底在何处。类似地,远地组件也不需要知道它们是否位于远地。这样通过加人合适的远地组件,应用程序完全不需要知道实际的组件到底在那里。在这里插入图片描述

对组件的需求

使组件的可以动态地将它们插入或卸出程序需要满足两个条件:

  1. 组件必须动态链接
  2. 隐藏(或封装)其内部实现细节

作者认为:

动态链接对于组件而言是一个至关重要的需求,而信息隐藏则是动态链接的一个必要条件。

动态链接

我们需要在运行时进行链接,否则我们在每次增减组件时还需要进行编译,这是用户做不到的,则没有意义。

为理解动态链接在这里的重要性,读者可以设想一下对于一个由组件构成的,但不能在运行时使用的应用程序,当用户需要改变其中的某个组件时会发生什么。此时开发人员不得不将整个程序重新链接或编译一遍,然后重新发行新的版本。但是这种重新编译或链接对于最终用户而言几乎是不可能的事情。即使他们知道如何重新链接,但他们可能没有链接程序,或者没有合适的链接程序。这种需要在每次改变一个组件时就将其重新链接一遍的程序同传统的铁板一块的程序实际上没有什么差别。

信息封装

用户在使用组件时,我们不能轻易改变连接方式(接口),当借口被修改时,则与之对应的用户的组件就会不匹配,整个系统就需要进行重新编译,这样组件就无法实现动态链接,失去了意义。我们要保证组件修改时对于其接口不要有修改,就需要把组件封装起来,接口同内部实现细节的隔离程度越高,组件或客户发生变化时对接口的影响将越小。

接口修改将导致程序的重新编译
不能改变接口
内部修改不能影响接口
需要进行信息封装

下面我们来看一下为什么动态链接需要信息封装。为组成一个应用程序,需要将各组件连接起来。当需要将某个组件用新的组件替换掉时,需要将此组件同系统断开,然后将新的组件连上去。显然新的组件必须按同样的方式连接到系统中,否则将需要重新编写、重新编译或重新链接这些组件。不论组件或应用程序是否支持动态链接,如果改变了某件同其件的方式,那么整个系统的体性实际上被破坏了,此时至少需要将整个系统重新编译一遍,甚至可能需要重新编码。
为说明上述情况为什么需要信息封装,下面先定义一些术语。对于一个应用程序或组件,如果它使用了其他组件,那么我们称之为一个客户,客户通过接口同其他组件进行连接。如果某个组件发生了变化但其接凵没有任何变化,·邓,么它.的客户不盂进行任似地,若客户发生了变化但没有改变其接口,那么它所的组也不需要任变。但是如果对客户或组件的修改导致了对接口的忤改,么接口的另一方也应发生相应的变化。
因此为充分发挥动态链接的功能,组件及客户都应尽其可能不要改弈它们帥接口。这意味它们必须被封装起来。也就是说,组件及客户的内部实现细节不能反映到接口中。接口同内部实现细节的隔离程度愈高,组件或客户发生变化时对接口的影响将越小。在接口没有发生任何变化时,对组件的修改将几乎不会对应用程序的其他部分产生什么影响

为实现封装,对于组件加上了一些限制:

  1. 封装编程语言,任何编程语言实现的客户与组件都可相互使用
  2. 组件必须以二进制的形式发布
  3. 组件升级必须同时适配新老的用户
  4. 组件在不同的设备,进程中都可使用

这种将客户同组件实现相应隔要求对于组件加上了一些限制,如下所列:

  1. 组件必须将其实现所用编程语言封装起来。任一客户都应能使任一组件,不论它们是用什么编程语言实现的,将实现用的编程语言暴露出来只会在组件及客户间引入新的依赖
  2. 组件必须以二进制的形式发布。如果想将实现组件的编程语言隐藏起来,那么在发布时它们必须是已被编译,链接并且马上就可以投入使用的。
  3. 组件必须在不妨已有用户的情况下被升级。一个组件的新版本必须既能够同老版本的客户一起使用,也可以同新版本的客户继续使用
    升级一个组件的新版本必须新版本客户一起
  4. 组件在网络上的位置必须可以被透明地重新分配。组件及使用它的程序应能够在同一进程中、不同的进程中或不同的机器上运行。客户对远程组件的处理方式应与对本地组件的处理方式是一样的。否则,当将某个本地组件移动到网络上的另外某个地方时,客户程序必须被重新编译
一、与语言的无关性

在一个与语言无关的架构中,任何人均可以编写组件,并且这些组件不会因为编程语言的发展而过时。

二、版本

向后兼容:老应用程序仍能够使用新安装的新版本组件

COM

COM是一个说明如何建立可动态互变组件的规范,它提供了为保证能够互操作,客户和组件应遵循的一些标准。
COM规范就是一套为组件架构设置标准的文档。本书中所开发的所有组件都将遵循这一标准。

COM组件是……

  1. COM组件是以WI32动态链接库(DLLs)或可执行文件(EXEs)的形式发布的可执行代码组成的。
  2. COM使用DLL将组件动态链接起来。
  3. 组件必须是封装。
  4. COM组件按照一种标准的方式来宣布它们的存在。使用COM的发布方案,客户可以动态地找到它所需的组件。
  5. COM组件是一种给其他应用程序提供面向对象的API或服务的极好方法。对于可用于快速构造应用程序、与语言无关的组件库的建立,COM组件也是不在话下。
  6. ……

COM不是……

  1. COM并不是一种计算机语言,COM所说明的是如何编写组件。
  2. 将COM同DLL相比或相提并论也是不合适的,实际上COM是使用了DLL来给组件
    提供动态链接的能力。
  3. COM也并不是像Win32 API那样的一个函数集。它更主要的是一种编写能够按面向对象API形式提供服务的组件的方法

COM并不是一种计算机语言。将COM同某种计算机语言相提并论是没有意义的。例如比较C++和COM谁优谁劣就没有什么意义,因COM和C++是各自有着不同的用途。COM所说明的是如何编写组件,但具体选用什么语言来编写则完全是自由的。在本书中,我们将使用C++来开发COM组件。
将COM同DLL相比或相提并论也是不合适的。实际上COM是使用了DLL来给组件提供动态链接的能力。在作者看来,利用DLL动态链接能力最佳的方法是COM。对于可用DLL解决的任一问题,均可以用COM组件更好地加以解决。对作者而言,除了用来支持COM组件外,在其他地方一般不会用到DLL。这正是因为COM可以有效地利用DLL。
COM也并不是像Win32 API那样的一个函数集。它并没有提供类似于MoveWindows这样的服务。(但COM确实也提供了一些组件管理服务,下面我们将要讲到,)相反,COM更主要的是一种编写能够按面向对象API形式提供服务的组件的方法。COM也并不是类似于Microsoft基本类库(MFC)这样的C++类库。COM给开发人员提供的是一种开发与语言无关的组件库的方法,但COM本身并没有提供任何实现。

COM库

COM当然并不仅仅是一套API。它具有一个被称作是COM库的API,它提供的是对所有客户及组件都非常有用的组件管理服务。

COM当然并不仅仅是一套API一它也确实需要一些具体的实现。COM具有一个被称作是COM库(COM Library)的API,它提供的是对所有客户及组件都非常有用的组件管理服务。当在非Windows系统下开发COM风格的组件时,要实现此API中的大多数函数并不是一件太难的事情。COM库可以保证对所有组件大多数重要的操作都可以按相同的方式完成。同时COM库也可以节省开发人员花在他们自己组件及客户的实现上的时间。COM库中的大多数代码均可以支持分布式或网络化的组件。Wirdows系统上分布式COM(DCOM)的实现中提供了一些同网络上其他组件通信所需的代码。这不但可以节省开发人员花在网络编程上的时间,而且可以使得他们无需了解如何进行网络编程。

COM方法

COM是我们可以将其作为一种编写程序的方法,COM也是一种组织软件的方法。

对作者而言,COM最值得称道的地方也许就是我们可以将其作为一种编写程序的方法。例如,可以在任何操作系统上使用任何编程语言按COM风格进行编程。为编写类COM组件,开发人员并不需要任何在Windows系统上实现的COM代码。本书前八章中的示例代码可以很容易地修改成不使用任何Windows代码。COM充分体现了组件编程的概念。同结构化编程及面向对象的编程方法一样,COM也是一种组织软件的方法。好的软件设计概念在COM规范中得到了充分的体现。

小结

COM可以满足前面讨论过的所有组件架构的需要。它使用DLL来提供可在运行时被替换掉的组件。COM借助于如下一些手段保证这些组件可以充分利用动态链接所带来的各种好处:

  1. 提供了一个所有组件都应遵守的标准。
  2. 允许使用组件的多个不同版本,而且这一点对于用户而言几乎是透明的。
  3. 使得可以按相同的方式来处理类似的组件。
  4. 定义了一个与语言无关的架构。
  5. 支持对远程组件的透明链接。

为实现上述目标,COM强制开发人员必须将客户和组件严格地隔离开。COM所具有的能力正是来源于这种强制性的隔离。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值