|
我们将使用一个简单的产品订货系统贯穿全文进行指导,该系统被分成两个主要的子系统――订单获取子系统和订单处理子系统。第一个子系统通过销售代表从消费者获取订单和付款信息。后一个子系统获取仓库管理员对产品订单队列的处理。产品订货系统合成两个COTS(Commercial off the Shelf,已下架的商品化)产品:存货系统处理产品存货,而订单仓库作为数据库(后者既用于产品订货系统又用于存货系统)。
表格 1 表示我们的系统体系结构使用分层模式(或分层风格)进行设计。该体系结构模式将在后面由设计模式和其他设计特征补足。
表格 1 讨论产品订货系统的分层体系结构模式
产品订货系统
- 用户界面(订单获取界面,订单处理用户界面,存货用户界面)
- 订单框架(消费者,付款,订单,订单行,记录器)
- 存货系统
- 网络(LAN)
- 订单仓库
模式怎样有助于视图集成?
在文章展开论述时,我们将揭示关于产品订货系统更多的细节。虽然,由于篇幅的限制,我们既不能在此表述整个系统,也不能阐述所有的集成技术。相反,如前面提到的,我们将集中于视图集成时模式承担的角色上。对应于图 2 中简述的三个集成活动,模式支持如下活动(下节将说明例子):
映射
模式支持不同抽象层次的视图之间的映射(交叉引用)。例如,一个高层框图指出使用一个已知后来在低层次框图中实现的模式。这样,这类模式存在于低层次框图的知识以及该模式粗略了解(如在[Gamma et al. 1994]和[Buschman et al 1996]中定义)的知识有助于在低层框图中自动鉴别。
模式也支持不同类型视图的映射。例如,模式描述经常指定其结构和它们的动态行为。那么,可以在我们的模型中使用这些知识来交叉引用结构化的和动态的信息。
变换
模式应用于变换的方法与它们在映射中的用途类似。对于变换,我们可以把它们用作抽象和转化。对于抽象,我们意指简化视图的处理。例如,如果我们想知道高层视图和低层视图是否一致,那么我们需要精炼高层视图或者抽象低层视图以使直接比较成为可能。前者不能自动进行,而后者可以。为了抽象视图,需要确定相关的片段,然后,它们被更加简单的事物替换。对此,模式是完美的原始资料,因为它们提供哪些片段属于一起的知识。我们可以使用模式知识抽象低层模式到高层模式(或者对等的单个部件)。
模式也可以如我们在映射中讨论的那样用于静态与动态结构之间的转化。既然模式经常用两种式样描述,我们可以通过结构推导行为(反之亦然)。这样,利用模式我们也可以转化视图。
分化
如图 2 中简述,分化强依赖于映射和变换。这意味着要在视图中找出不一致性,我们需要确定其建模元素的关系,并且需要找出从一个视图到另一个视图变换信息的方法。没有前一个步骤我们不能知道要比较什么信息,没有后一步,我们不知道怎样比较。一旦上述步骤完成,我们可以使用两个主要技术比较视图:
(图形)比较:依靠变换的视图和原始视图的对比进行比较。该技术暗示:一个视图可以保留充分完整的风格变换为另一个视图。
约束和规则检查:我们频繁地发现视图不能广泛的变换为另一个视图,但它的少部分和片段可以。在这种情况下,我们可以使用规则和约束来论述和分析这些片段。
对于分化,设计模式并非直接有用,然而,我们通过映射和变换收集到的有关视图的信息却可以。我们已经简短地讨论模式怎样有助于映射和变换视图。在这些例子中,比较视图是直接的,因为映射和变换启用直接(图形)比较。无论如何,模式在约束和规则检查中也非常有用。例如,我们在表格 1 中介绍的分层模式定义了自然的约束:用户界面只允许与订单框架对话,订单框架依次只能与存货系统对话等等。该体系结构的模式影响了设计的结构和它的行为。
在产品订货系统中使用模式
本节通过说明模式可以怎样在我们的产品订货系统语境中应用于集成活动的例子补充上述论述。
分化
图 3 使用UML包说明我们系统的高层设计视图。该图显示主要订单系统部件(或子系统)的交互。关于分层体系结构的知识现在可以帮助我们在表格 1 中的体系结构和图 3 的设计之间自动确定不匹配。表格 2 总结两个视图对立的约束。 体系结构视图约束从表格 1 导出。它们定义我们系统层次之间的调用依赖关系(例如,用户界面依赖于订单框架)。图 3 是设计视图约束的基础。该图说明一个含有一套包以及它们之间调用依赖的UML包图(包和依赖的语义在[Booch-Jacobson-Rambaugh 1997]中定义)。
表格 2 体系结构上和设计视图对立的约束
体系结构的视图约束
体系结构[用户界面取决于订单框架];
体系结构[订单框架取决于存货系统];
体系结构[存货系统取决于网络];
体系结构[网络取决于订单仓库];
设计视图约束
设计[订单获取UI取决于订单框架];
设计[订单处理UI取决于订单框架];
设计[存货UI取决于存货系统];
设计[订单框架取决于存货系统];
设计[订单框架取决于网络];
设计[存货系统取决于网络];
设计[网络取决于订单仓库];
映射
设计[订单获取UI] 映射到 体系结构[用户界面]
设计[订单处理UI] 映射到 体系结构[用户界面]
设计[存货UI] 映射到 体系结构[用户界面]
设计[订单框架] 映射到 体系结构[订单框架]
设计[存货系统] 映射到 体系结构[存货系统]
设计[网络] 映射到 体系结构[网络]
设计[订单仓库] 映射到 体系结构[订单仓库]
完整性规则
对于所有体系结构的视图约束存在设计视图约束;
例如:
体系结构[用户界面取决于订单框架] =>
存在:设计[订单获取UI取决于订单框架] 或者
设计[订单处理UI取决于订单框架] 或者
设计[存货UI取决于订单框架]
一致性规则
对于所以设计视图约束存在体系结构约束;
例子:
设计[订单处理UI取决于订单框架] =>
存在:体系结构[用户界面取决于订单框架]; |
表格 3 描述产品订货系统的分层体系结构模式
产品订货系统
|
用户界面(订单获取UI,订单处理UI,存货UI)
|
订单框架
|
存货系统
|
网络(LAN)
|
订单仓库
|
建立这些约束是变换的责任,并且在这种情形下能够自动完成。例如,利用我们在表格 1 中的分层模式的知识我们可以自动导出层间的调用依赖关系。优点是模式的语义只需要定义一次并且可以在以后重用。视图的语义和符号也可以看作模式。这样,图 3 的包图带有一套预定义的相关约束。一旦定义,就可以对包图的不同实例导出设计约束。 表格 2 的映射部分定义了体系结构视图(表格 1 )和设计视图(图 3 )部件之间的关系。在这个例子中,用于映射的模式使用不是那么明显。我们将在后面讨论它们对于映射的使用。 表格 2 中最后两个部分是部分的分化活动。在那里,定义了两类规则,一个用于一致性,另一个用于完整性。如果体系结构定义的一些部件或连接器没有反映在设计中,就可能显示潜在的不完整。在另一方面,如果设计与体系结构抵触,那么这可能指出潜在的不一致性。另外,对于每套我们比较的视图,规则只需要定义一次;那些规则然后可以重用。在体系结构和设计实现之间确定不匹配现在是评估规则和约束的事情。这样揭示了没有完整性方面的不匹配情况,然而,有些不一致性方面的不匹配:1) 存货UI部件对于存货系统的依赖与分层体系冲突,用户界面不允许不经过订单框架直接与存货系统进行交流。 2) 类似地,订单系统要求使用存货系统访问网络。
|