通过接口的实现提供多态性

部件对象模型 (COM) 的最显著的特性是对象具有实现多个接口的能力。除多态性外,多个接口还提供了增量式或渐进式开发的方法,在发生改动时不必重新编译系统中的所有部件。

以由密切相关的函数组成的接口方式定义功能,就可以只实现部件所需的功能,需要时再通过实现附加的接口来扩展其功能。

由于部件的新版本在添加新接口或增强接口时,可以继续提供原有的接口,这样就简化了保持兼容的问题。如果有必要,客户端应用程序的后续版本就可以使用它。

继承与多态性

如《Visual Basic 程序员指南》“用对象编程”的“多态性”所阐述的,绝大多数面向对象的编程工具通过继承来提供多态性。对小规模的开发任务来说,这是一种很有效的技术,但大规模的系统中,这种方法是有问题的。

一方面,导致这些困难是由于需要对继承树深处的类作必要的改动。为了获得改动后的优点必须进行重编译。如果到发布新版本的最后期限时,重新编译失败将导致严重的后果。

更严重的是,过分强调继承驱动多态性往往导致大量的资源从开发任务到前沿设计任务的转移,在最终用户可能发现─ 通过掌握的经验─ 系统是否真地完成了期望的目的之前,却没有解决积压的开发任务或缩短时间。

所以,快速原型工具和快速应用程序开发 (RAD) 比 OOP 工具得到更广泛的接受。

Visual Basic 与 COM

Visual Basic 遵循 COM,强调多接口是提供多态性的一种更灵活的途径。这样,软件可以一个接口一个接口地渐进开发,而不是原来那样通过一个很长的设计过程从所有必须的先例派生。

刚开始时,对象可以比较小,只具有最少的功能。随着在实践中逐渐明确该对象应该提供的功能,再不断实现这些新的功能。当实现新的接口时,继续保留原有代码以支持旧的接口。

Implements 功能

Visual Basic 使用 Implements 关键字来提供一种与辅助接口公用的方式。例如,如果工程引用了描述 IFinance 接口的类型库,则可以在类模块中包含以下代码:

Implements IFinance

由于类型库只包括接口,不包括实现方案,因此可以按“标准接口的实现与使用”所描述的,给 IFinance 接口的每个属性和方法增加代码。

接口即协议

为使用 Implements 功能而创建接口,就是将其永久地具体化。接口不变性是部件设计中很重要的原则,因为它保护原有的针对该接口编写的系统。

当接口确实需要增强时,就应创建一个新的接口。可以称新接口为 Interface2,以说明新接口与已有接口的关系。

频繁地生成新接口将使部件中充斥大量的无用接口,好的接口设计应该小而彼此独立,以尽可能减少对性能的影响。

因素化接口

确定属于接口的属性和方法的过程叫做因素化

一般而言,应使接口的功能密切相关。接口功能太多会使接口很笨拙,把功能分的太细又会增加额外的负担。例如,下面的代码调用 Velociraptor 类的三个不同接口:

Public Sub CretaceousToDoList(ByVal vcr1 As _
      Velociraptor, ByVal vcr2 As Velociraptor)
   Dim dnr As IDinosaur
   Dim prd As IPredator
   vcr1.Mate vcr2
   Set dnr = vcr1
   dnr.LayEggs
   Set prd = vcr1
   prd.KillSomethingAndEatIt
End Sub

要使用 IDinosaur 和 IPredator 接口的方法,必须把对象赋给正确接口类型的变量。

使用灵活数据结构的接口一般比使用固定数据类型的接口经久耐用。

如上面提到的,设计接口不象创建大型继承树那样容易出错。如果以较小的接口开始,则很快就可以让系统的一部分先运行起来。以后再通过添加接口逐渐扩展这个系统,从而获得真正面向对象编程的优点。

创建和使用接口的工具

关于创建接口的技术在以下相关主题论述,在 MkTypLib 应用程序 (MIDL) 的文档中也有介绍。

详细信息   Implements 功能在《Visual Basic 程序员指南》“用对象编程”的“多态性”中详述。