
10.1 基于构件的系统静止状态下的结构建模
在软件开发和设计时 ,可能 有这样的想法:正 在开发的软件系统的某些功能是否可以直接用别人已经完成的并且具有相同功能的软件模块来代替,这样可以大大节省 时间;另外,为了使所开发的软件系统的某些功能模块在将来更容易更新和替换,而不得不考虑如何使所开发的功能模块与系统的其他功能模块之间有最大程度的松耦 合机制。正是在所有上述想法的驱动下,软件工程领域出现了一种软件开发技术,称为基于构件的开发( ComponentBase dDevelopment , CBD) 。
在该方法的指导下,构件对用户来说能够”即插即用“,即能从所提供的构件库中获得合适的构件并重用;对 供应商来说,这种软件构件便于用户裁剪、维护和重用。
为了实现基于构件的软件开发的设计思想,必须将系统划分为若干个可管理的子系 统,再把子系统中的类用接口进行封装,以便组成构件内 部高内聚( Cohesion汃构 件之间松耦合( Coupling) 的结构。UML提供构件图来实现基于构件的系统结构建模。
10.2 构件和构件图
10.2.1 构件
目前构件还没有统一的定义。根据DonaldBell在UMLBasics:TheC01n/Jonent Diagram一文中所述,UML2.0改变了传统构件概念的本质意思,在UML2.0中, 构件被认为是在一个系统或子系统中独立的封装单位,它通过一系列的接口对外界提供功能。也就是说,在UML2.O中,构件被认为是独立的,是呈现事物的更大的设计单元,这些事物一般将使用可更换的构件来实现。构件提供一个或多个接口。在本书中,我们更倾向于把构件定义为:在软件系统中遵从并实现一组接口的物理的、可替换的软件模块。在这个构件定义中,强调了构件的两个重点接口和可替换(或称为重用)。
构件的实施细节应 被隐藏,它使用一系列 的供接口( P rovid ed In terface ) 提供它的功能 ,使用需接口( Req ui red Int erface ) 接收其他构件提供的功能。通过使用接口, 可以避免系统中 各个构件之间发生直接依 赖关系,有利 千新构件的替 换。如果构件间的依赖关系与接口有 关,那么构件可以 被具有同样接口的其他构件替代。
当前主流的构件模型规范有以下三种。
(l ) O MG 的 CORBA 构件: 跨越了各种平台和语言的限制。
(2) SunMicro systems的 EJB构件: 跨越异种平台。
(3) Microsoft的 COM+ 构件:仅限于 Windows系列操作系统。
10.2.2 构件图
构件图( Compon ent Diagra m) 为系统中的构件建模,它展示了构件间的相互依赖关系。
构件图是 U ML 中最重要的建模图示语言之一。它可以建立系统中的类、类的内部结构(类的属性和操作)以及类与类之间的各种静态关系模型。构件建模的目标是把系统中的类分布到更大的内聚构件中 ,并显示系统构件间的结构关系 。构件图由构件、接口、关 系、端口和连接器组成 ,它的表达方式 为:

10.3 构件图的表示方法
10.3.1 构件
UML 提供许多种表示构件图的方式,基本构件是一 个可替换的软件包。如图 10-1 所示的符号可视化地 表示了一个构件。

在 UML 2. 0 中,构件用加构 造型 < < co m po n e n t > > 的矩形框来表示。如果没有详细地显示构件的细节,可以 将构件的名字放置在 矩形框的中央。可以 在矩形框的右上角显示一个构件的图标,这个图标其实是 UML 2. O 之前表示构件的符号,即用左侧加两个小矩形的矩形框表示构件。
10.3.2 供接口和需接口
构件为什么要用接口呢? 构件中有非常多的功能,假如有一个类要使用构 件中某个类的某个方法,但当构件中这个具体的方法发生变化时(例如方法名字的变化或方法内容的变化),那么该类就不 能应用构件中的相应内 容了。应用接口可以 隐藏具体的实现细节 ,这样 ,构件中的内容可以任意变化,而接口却是相对固定的。
构件向外 部展现两种接口 : 供接口和需接口。
供接口表示构件为客户提供的 功能 ,它告知用户构件如何 被使用。构件至少要 有一个供接口。
需接口表示为了使构件工作,构件必须从其他服务中所获得的功能。需接口表示 该接口是构件的成员变翟或构件中类的成员变鼓。
供接口用"棒棒糖”式 的图 形 表示,即由一个封闭的圆形与一条直线组成; 需 接口用“插座”式的图形表示,即 由一个半圆与一条直线组成。如图10-2 所示的例子为P P S 项目中的产品预定构件,须注意它的供接口和需接口。

图 10- 2 中的构件名为 O r d er Prod uc tS ess ion ,为了向两种不同的用户提供服务,它提供了两种不同的供接口: 接口 ! C us to m e r 为一般客户提供服务,接口 ! S a le s m a n 为销售人员提供服务。
为了完成它的工作,OrderProductSession构件也需要其他三个不同的构件提供的 服 务 :Or d e r byRet a il 、 Ord e r byBa tch 和OrderbyManual, 用I R e t a i ! O rd e r、IBatchOrder和IManua!Order分别表示三个需接口。
与图10-2相对应的代码如下所示:

在 J a va 语言中,供接口通过关键字 im ple m e n t s 来显式地表示,需 接口被类所使用的任何接口类型隐式地定义。
10.3.3 构件间的关系
如果一个构件有一个需接口,则表 示它需要另一个构件或者类为它提供服务。为了表达构件与其他构件间的关系,供接口与需接口之间用一个表示依 赖的箭头(即虚线加一个开箭头)连接起来,该箭头从需接口引出,指向服务供应者提供的供接口,如图10- 3 所示。

图 10- 4 用一个装配连接器(A s s e m b ly Co nn ec to r ) 表示构件之间的关系,稍 后将介绍装配连接器.

更简单的,可以忽略构件间的供接口和需接口,而直接在构件间画上依赖关系,如图 10-5所示。

10.3.4 实现构件的类
构件需要包含和使用一些类来实施它的功能,这些类实现了这个构件。可以在构 件中画出这些类以及类间的关系,如图 10- 6所 示。
更直接的,可以直接在构件和实现它的类之间绘制依赖表示这些类实现了构件。

图 10-6 也可以用图 10-7 表示。

10.3.5 外部接口一 端口
组合构件的外部接口用一个尾部加小方块的正常接口表示,这个小矩形框被称为端口(P o r t ) 。端口是 U M L 2.0引入的一个概念。端口提供一种方法来显示建模构件所提供或要求的接口如何与它里面的部分相关联,如图10-8所示。

10.3.6 连接器
为了展现功能的实现,连接器( Co n necto r ) 将一个构件提供的接口与另一个构件必需的接口绑定到一起。UML 2. O 提供了以下两种类型的连接器。
(l) 代理连接器( Del eg a t io n C o n n e ct o r ) : 连接外部接口的端口和内部接口。
( 2) 组装连接器( Assem blyCo nnect or ) : 组装连接器表示构件之间的关系,它连接构件内部的类,将一个构件的供接口和一个构件的需接口捆绑在一起。
10.3.7 显示构件的内部结构
一个构件的内 部可 能包 括多 个 其他的构 件,这 样 的 构 件 称 为 复 合 构件( CompoundComponen t) 。复合构件中的构件称为子构件( Subcomponent ) 。图 10-9 显示了 PPS项目中一个称为 ProducePlanning的复合构件及其内部结构。这个例子标明了构 件图的所有组成元素。

在图 10-9中,ProducePlanning构件提供了 lproducePlan接口并需要!customer 接口为其提供服务。ProducePlanning构件由 三个构件组成: O rder、ProducePlan和Product。ProducePlanning的 IproducePlan和 !customer接口符号在构件的边缘上均有一个方块,这些方块就是上面介绍 的端口。通过使用端口 ,可以从外 部实例中分离出ProducePlanning构件的内部构件。IproducePlan 端口代表ProduceP lanning 构件的lproducePlan接 口。同时,内部的 Order 构件要求的!customer 接 口被 分配到ProducePlanning构 件 必 需 的 !customer端 口。 通 过连 接 !customer端 口,Pro d uceP lann i ng 构件的内 部构件(例如 O rder 构件)可以具有代表执行 端口接口的未知外部实体的本地特征。必需的 !c us tomer 接口将会由其他外 部构件实现。
9. 4 总 结
本章介绍了构件图。构件图表示了构件之间的依 赖关系,每个构 件都可以实现一些接口 ,并使用另一些接口 。如果构件间的依赖关系与接口有关 ,那么这个 构件可以被具有同样接口的其他构 件替代。
我们强调了构件的概念,构件是系统高层的可重用的组成部件,指任何可被分离 出来、具有标准化的、可重用的公共接口的软件,它将系统中可重用的块包装成具有可替代性的物理单元。系统的实现视图用构件及构件间的接口和依赖关系来表示设计元素(例如类)的具体实现。
构件图是展示各构件的组织 和依 赖关 系的图。注意 ,构件图 只有描述符形式 ,没有实例形式。要表示 构件实例,应使用部 署图。第 11 章将介绍部署图。

