学习如何扩展 IBM? Rational? Software Architect
并利用您自己的定制模式来自动化地设计软件。通过使用特性集,您可以在设计 SOA 和其它解决方案时,提高生产力。您还可以使用这些自动化的特性来提高解决方案的质量,并且支持治理过程。
预备知识
了解从本教程中能够得到什么,以及如何最有效地使用本教程。
关于本系列
要想获得模型驱动开发(model-driven development,MDD)的好处,您的设计和开发环境应该具有以下特征:
用于复用的最佳实践:人们可以复用已证实的解决方案来再现问题,并且为其他人提供解决方案来复用。
基于角色的工具:工具是针对手边的任务以及执行该任务的人的角色的(举例来说,业务分析人员或
IT 架构师)。
过程支持和指导:在环境中总是有方法或过程指导。
可扩展的平台:团队可以扩展或定制环境以适应他们的需求。
自动化:框架的底层元模型和映射涉及从较高层次的抽象到较低层次的抽象,以及最终到可执行代码的模型的半自动化的转换。也可能从较低的抽象层追溯到较高的抽象层。
这些是 IBM? Rational? Software Delivery
Platform 以及,更确切地说 IBM? Rational? Software Architect
的所有特性。在本系列教程中,您将了解到,当您创建基于 SOA 的解决方案时,如何扩展平台及其功能来帮助您。本系列的第
1 部分,创建 UML 概要文件和模型模板,讨论了 SOA 和 IBM? Rational? Software
Architect 的可扩展特性之间的关系。它向您展示了如何能够利用您自己的定制模板和概要文件,在 Rational
Software Architect 自动地设计 SOA 解决方案。
当学习了本系列之后,您应该能够自主地描述特性,在 SOA 的设计中扩展
Rational Software Architect。您将会了解什么是建模,以及如何创建 UML 概要文件、模型模板、UML
模式、转换,及可复用的资产。
关于本教程
在本教程中,系列的第 2 部分,我们将讨论您如何能够利用 Rational
Software Architect 中您自己的定制模式实现来自动地设计 SOA 解决方案。模式实现可以提高您的生产力、改进架构的实施,并且提高质量。特别是,我们将讨论如何创建您自己的
UML 模式,从而更好地遵照您自己的组织的最佳实践。
目标
当完成了本教程之后,您将更好地了解如何利用 Rational Software
Architect 中的工具和特性来支持基于模式的工程。您可以使用这些自动化特性来提高您团队的生产力、提高解决方案的质量,并且支持您的治理过程。这些自动化特性将您的最佳实践编码,这常常是针对您的组织的,并且是组织的竞争优势的一部分。
在完成了本教程之后,您将能够描述您在 Rational Software
Architect 中创建模式所采用的不同方式。此外,您将能够创建简单的 UML 模式。
必备条件
为了从本教程中获得更多价值,熟悉以下这些方法和软件是有帮助的,但不是必要的:
UML,统一建模语言(Unified Modeling Language)
Rational Software Architect、Rational
Systems Developer,或 Rational Software Modeler
SOA,面向服务的体系结构(service-oriented architecture)
Patterns,模式,在给定的环境中对已知问题的经过证实的解决方案
参见本教程末尾的参考资源部分,查看关于这些主题的有用链接。
系统需求
为了完成本教程,您应该安装以下软件(参见参考资源中的试用版):
IBM Rational Software Architect V7.0
或
IBM Rational Software Modeler V7.0
引言
在“用 Rational Software Architect 设计
SOA 服务”系列中(在参考资源中列出),我们介绍了如何使用模型来获取基于 SOA 的解决方案的设计。我们已经能够处理许多不同层次的抽象,利用现有的
UML 概要文件、模型模板、UML 模式,和转换。这些工件已经帮助指导我们设计,并允许我们按照需要生成详细的工件。
然而,我们面临了疑惑:“我们如何能够使用同类型的支持和自动化,却又依照我们自己的最佳实践呢?”在本系列的第
1 部分中,我们讨论了 Rational Software Architect 中支持的两类工件,也就是,UML
概要文件和模型模板。我们讨论了它们是什么,以及如何创建您对这些工件的您自己的实现。因此,我们应该能够创建您自己的概要文件和模型模板。
在本教程中,我们将展示 IBM Rational Software Architect
如何支持软件开发的基于模式的工程(patterns-based engineering,PBE)的方法。在
PBE 方法中,我们利用不同类型的工件,包括:
UML 模式:模式的一般的定义:在给定环境中,对已知问题的已证实的解决方案。在
Rational Software Architect 范围内,UML 模式是用 UML 显示的,并且是交互式地应用的。它接受模式范围内的有限数量的元素作为输入。
转换:转换是 Rational Software Architect
中一种特殊的模式。在 Rational Software Architect 中,UML 模式和转换之间的关键差别是用户交互和输入或输出范围。转换经常以批量方式应用,它接受来自源模型的元素,然后将它们转换为目标模型中的元素。转换将在本系列下一个部分中涉及到。
插件:Eclipse 平台本质上是使用插件的机制。所有添加到该平台中的功能都是以插件形式存在的。Rational
Software Architect 是一组(大型)提供针对建模、SOA 开发等等的特性的插件。我们通过将模式、转换,和其它资产打包为插件来共享它们。
Pluglet:Pluglet 是轻型插件。它用起来很快且容易,可以让
Rational Software Architect 的用户与平台的底层 API 交互,从而访问关于该用户工作区中的模型、模型元素,和项目的信息。您可以将
pluglet 用于环境中的一些脚本化的任务,或者将其作为探究和测试与底层平台的交互的方式。
RAS 资产:可复用的资产规范(Reusable Asset Specification,RAS)是
Object Management Group(OMG)的标准,它描述了如何打包、分配,和消费可复用的资产。Rational
Software Architect 支持该标准,简化您使用可复用资产的方式。RAS 资产将在本系列后面的部分中涉及到。
当您学习本教程和系列的下一个部分时,将更详细地讨论这些工件。我们将讨论这些工件是什么,您如何构建它们,最重要的是,您如何能够组合地使用它们。在我们深入到这些工件的细节之前,了解一些相关的术语是很重要的。
提示:
在本教程这个部分中的一件要注意的重要事情是,我们在使用 Rational
Software Architect Version 7。参见参考资源的链接,下载完全功能的试用版。
基于模式的工程术语
我们已经看到了“在给定环境中对已知问题的已证实的解决方案”这种模式的定义。在这个简单的定义中,有一些我们一定不能忽视的关键思想:
已证实的解决方案:使用模式是要获取最佳实践。该定义的一个很明显的方面是解决方案要有效。如果模式没有效,那么对它投入时间和努力就没有意义了。
已知的问题:要更好地了解解决方案,您还需要了解要解决的问题。如果您不了解问题,那么可能会试图对不相关的问题应用模式。
给定的环境:这个已证实的,最佳实践解决方案只在某些情况下应用于这个问题。如果我们试图将模式应用于所有的情况中,那么我们将发现我们总是得不到预期的结果。我们必须在选择模式时小心谨慎,从而确保该模式适合环境。在模式和其应用的环境之间不匹配的情况下,我们甚至最终会消极地影响解决方案。
知道了这些,现在我们需要区分模式规范和模式实现。
模式规范是书籍和文档中找到的形式地写出来的模式描述。该规范是我们传统上认为的模式,它包含以下信息:
模式有效的环境
要处理的问题的描述
该环境中使用的力量的描述
应用上模式的解决方案的描述
应用模式的策略
一列应用模式的结果
这些年来,这是我们使用模式的主要方式。我们已经撰写了规范、共享规范,并且在我们构建解决方案时遵照规范。它们令我们了解最佳实践、复用思想,并且更容易地与他人交流。然而,生产力的提高是有限的,因为当提到根据模式规范创建解决方案时,就由个人来阅读规范来解释,然后创建元素。如同人们需要阅读、解释,并手工实现的大部分东西一样,每个这样做的人都将构建出有一点不同的解决方案。用这种方式,尽管所依据的是相同的规范,但是同样的模式也可能最终导致稍微不同的解决方案。此外,每次我们需要应用模式时,我们都需要手工地重复这些步骤。
模式实现是在特别的环境中自动应用模式的工件。该工件很容易共享和复用。模式在开发环境中成为具体的工件。在
Rational Software Architect 中,模式实现表现为:
1.UML 模式
2.转换
3.插件
4.向导
有了模式实现,我们现在能够处理一些在用模式规范时观察到的弱点。给定适当的输入,不管谁使用该模式,模式实现将生成同样的输出。同样,如果原来我们需要多次应用模式,那么再次应用模式是快速且简单的。
要记住实现不能取代对规范的需求。很可能的是,一个模式规范可能导致零个或多个模式实现。然而,我们应该不会遇到这些情况,就是我们有一个没有模式规范的模式实现。
模式实现的好处
遵照基于模式的工程方法进行开发会带来许多重大的好处。
提高生产力
有多少次在您做项目时您思量过“我已经解决过这个问题,为什么我必须重新创建该解决方案?”工作的困难、有趣,且有创造性的部分是解决初始的问题。当问题解决时,我们希望利用该解决方案并且快速且一贯地再次应用它。此外,我们希望其他人可以使用该解决方案,以便他们也从中得到好处。这些年来,我们发现自动化能够比人更快速地再次生成解决方案的实例。这可能十分明显,因为我们期望自动化能够比我们手工执行任务要更快。因此,我们正好通过将解决方案的应用自动化来提高生产力。
使用模式实现所带来的一个有趣的方面是它们支持并将 points of
variability(可变点)自动化。可变点允许我们调整模式工作的方式,裁剪其输出,从而生成针对手边任务的解决方案。在过去,我们会复制并粘贴实现,然后根据需要调整代码。现在,取而代之,我们在创建模式实现时分析解决方案,以便在应用模式时,根据用户提供的信息来对其进行定制。这种很容易地调整并配置模式,并且取得一致结果的能力给我们带来了额外的生产力的提高。
最后但非最不重要的,模式实现的使用允许整个团队自动地使用并遵守最佳实践。不管技能集和经验水平,团队成员都可以利用专家和已证实的解决方案的经验。团队成员不需要了解构建初始解决方案时和创建现在表示解决方案的模式时的所有细微差别。
改进架构的实施
当我们面临着全球分布的开发、技能专门化,和跨团队的变化的技能水平所引入的挑战时,实施架构决策和风格是一件困难的事情。不管我们的团队成员是否在一个屋、在一个城市,或者遍及全世界,确保我们都共享同样的构想,并且向着同样的方向工作是一种挑战。其中,产生的问题包括时区、语言、文化,和经验水平。书面文档、幻灯片展示,以及“图片”对这些问题的处理不起作用。模式实现为我们提供了共享最佳实践、解决方案,和设计决策的途径。
此外,我们可以使用模式实现生成解决方案的大部分,因此限制并隔离了其他人需要向解决方案添加内容的位置和方法。就技能专门化来说,我们发现我们不得不接受来自其他人的工作产品,然后,在我们做出贡献之后,我们需要将工作产品传递给其他人。模式实现帮助约束了工作的输入和输出将会是什么。就像从资产中得到预期的输出一样,对可变点进行编码和通告。因此,我们有清楚且自动的,关于工作产品如何沿生产线移动的约定。
模式实现还提供traceability(可溯性),或者将所有写出的代码追溯回需求的能力。当使用
Rational Software Architect 时,我们能够利用它与 IBM? Rational?
RequisitePro? 和 IBM? WebSphere? Business Modeler 的集成,利用商业所有者指定的需求,来创建模型元素(例如用例)之间的连接。然后,当我们工作于覆盖模型和代码的抽象层之上时,我们能够添加显示设计中的元素和需求之间的关系的进一步的连接。模式实现可以用于自动化创建可溯性链接,因为它生成解决方案中的元素。有了这样的可溯性的支持,我们就可以回答这样的问题了:“变更的影响是什么?”和“为什么这样建立此解决方案?”。
提高质量
如果结果的解决方案的质量很差,那么生产力和架构的实施都是徒劳的。根据定义,我们的模式实现是基于最佳实践的。同样,我们通过使用模式已经步入了质量的范围。我们仍旧不得不利用判断来选择模式,因为环境扮演了重要的角色,但是我们可以使用与模式实现相关联的模式规范和其它的文档来指导我们。
就像先前讨论的一样,我们还得益于在团队中更好地利用专家技能。专家能够构建重复他们的最佳实践解决方案的自动化。因而,与其重复他们的工作,提供同样的解决方案,倒不如专家构建自动化,然后转移到需要他们关注的下一个问题上。
最后但非最不重要的,如果模式实现中出现错误,那么我们可以修正缺陷,然后通过重新应用模式来重复新的切改进的解决方案。相反,如果我们根据规范手工地实现模式,那么我们将不得不修改解决方案所在的每个代码实例。这种手工的工作是耗费时间的,并且会有将新的人的错误引入到假定的解决方案中的危险。
还有许多其他的方式来继续讨论模式实现的好处。但是,让我们通过关注一些要点来概括一下。模式实现是需要在这些情况下考虑的技术:
解决方案被重复地应用
需要使用最佳实践解决方案
分配给项目的时间总量是有限的
项目的质量是关键需求
专家经验是有限的
支持工具和工件
形形色色的增强元素
当创建基于模式的解决方案时,有许多可以组合地使用的元素可以用于进一步提高所获得的收益。这些元素可以分为三个关键的组(图
1):
提供自动化的元素:这个组包含了例如 Rational Software
Architect UML 模式、转换、向导,和 Eclipse 插件的东西。这些是组成模式实现的主要元素。
支持使用自动化的元素:这个组包含例如概要文件、模型模板,和 pluglet
的东西。
解释过程并提供指导的元素:这个组包括 IBM? Rational? Method
Composer 插件、以及 Help、犯规卡,和其他形式的文档。
图 1. 元素类型
我们已经涉及了前两类的元素,因此让我们来考虑第三类。就像能够构建根据最佳实践将开发自动化的资产一样重要的是,要能够确保您的用户了解如何使用生产出的资产。为此,您需要找到有效的方式来告诉人们如何使用这些资产。对此您有一些可选项:
使用 Rational Software Architect 中的底层
Help 系统创建 Help 文档。
创建可以被组织和团队用来构建它们的定制的开发过程(包含如何使用您的资产的描述)的定制的
Rational Method Composer 插件。
组合使用元素的方法
既然您基本了解了所有这些元素都是什么,以及它们扮演的角色,那么让我们来看看如何对它们进行组合使用(图
2)。
图 2. 组合元素
从左至右,首先获取解决方案的输入模型。输入模型获取对于手边的任务所独特的信息。
与其从空模型开始,倒不如在构造模型时选择模型模板作为指导,并且看看在模型中您需要的元素。
提示:
您经常会发现,模型模板有许多已经应用的概要文件,因此向您提供针对任务的语言。在您处理模型时,您可以随需要手工地添加元素,并且向元素应用原型。原型用于表示有额外的领域专用的含义的元素。您还可以在模型中应用
UML 模式,从而自动地创建并修改模型中的元素。
作为 UML 模式应用的一部分,模式可能利用应用于模型的概要文件,以及模型模板的知识。当您达到想要移动到下一抽象层的位置时,您可以使用转换来将过程自动化。转换将解释源模型中的元素,并且,利用一些列规则,将模型元素转换为下一抽象层上的元素。
当在抽象层之间移动时,您可以从较抽象的移动到较详细的,或者您可以从较详细的移动到较抽象的。不管方向如何,很重要的是要记住,在不同抽象层的元素之间经常没有直接的一对一的映射。当从较抽象的移动到较详细的时,经常有输出端元素。这意味着较高层模型中的元素将最终成为较低层模型中的一个或多个元素。根据我们构建模式解决方案的经验,这里有一些要记住的关键思想:
当人们遵照自底向上或两头向中间的方法时,会取得构建模式实现的大部分的成功。自顶向下的方法经常更困难且更有风险。如果您回忆起模式是基于已证实的,已知的解决方案的话,这就有很大意义了。如果您没有构建模式所源自的解决方案,那么它是真正的模式吗?
当构建获取模式规范的输入的用户表示时,最小化用户不得不提供的信息量。这有两种表现方式:
限制与您的自动化一起的元素和图的量。虽然有许多组合的元素和图可用,但是这不意味着您必须用它们。保持简单。
如同为数据库指定模式一样,您需要规范化传递给模式实现的信息。让用户提供对于模式的应用是独特的原子值。如果某个值可以计算得来,那么就不要要求用户来提供该信息。同样,如果信息对模式的特殊应用不是独特的,那么将该信息嵌入模式中。
在您阅读本系列余下部分时牢记这些点。您不仅想要构建模式实现,您还想要构建人们将复用的高质量的模式。如果缺少了质量,或者资产很难使用,那么您的投资就是浪费的。
UML 模式
UML 模式应用于模型中,允许您指定细节并且根据最佳实践在模型中创建元素。如前面部分中讨论的,UML
模式经常和 UML 概要文件组合使用,向模型元素中添加置标。它还可能向模型添加元素,或者修改现有元素的方面。要记住的一件重要的事情是
UML 模式工作于模型之中,但转换工作于模型之间。许多 UML 模式是 Rational Software
Architect 中默认提供的,它们基于 Gang of Four(GoF)设计模式。您可以在 Pattern
Explorer 中访问这些模式,以及您安装的任何附加的模式(图 3)。
图 3. Pattern Explorer
注意:
名为 My Struts Patterns 的 Patterns Library
不是标准的 Rational Software Architect 安装的一部分。在这种情况下,我们已经构建了自己的模式来使用(与处理对基于
Struts 的解决方案建模相关的模式)。当您构建您自己的模式时,将模式分组到库中,使它们很容易找到并使用。
构建定制的 UML 模式
在此部分中,您将构建 SOA 领域中的简单的定制的 UML 模式。DEV498
课程“Pattern Implementation Workshop with IBM Rational
Software Architect”,提供了更多的细节和指导(参见参考资源)。
模式规范
理论上,您将发现,在一个项目上(或者许多项目),出现了复现的解决方案。我们想要识别该复现的解决方案,并且通过确定模式中指定的角色、它们的多重性、它们之间的依赖性,什么时候使用解决方案,使用解决方案的影响,等等来开始模式分析。Exemplar
analysis(样本分析)是执行该分析的已证实的方法。我们将在本系列后面部分中介绍样本分析。
在完成样本分析时,我们将定义模式中涉及的角色、它们的属性、派生的属性,和输入模型,并且我们将开始模式实现和规范。对于本教程,您的
UML 模式将实现 Service Provider 模式。表 1 展示了该模式的模式规范。
表 1. Service Provider 模式的规范
撰写模式实现
在 Rational Software Architect 中,UML
模式是基于 Eclipse 的,利用许多专用的 API(包括模式 API、UML 2 API、EMF API
等等)的插件。要开始创建您自己的模式,遵照这些步骤:
选择 File > New > Project。
在出现的向导中,用插件(Plug-in)替换类型过滤器文本(Type
filter text),然后选择 Plug-in Project(图 4)。
然后单击 Next。
图 4. Plug-in Project
在下一屏中,Plug-in Project,输入项目名称 com.ibm.myPatternLibrary。
保留其余的默认值,并单击 Next。
接受向导下一页上的默认值,标题为 Plug-in Content,并再次单击
Next 。
在向导的 Templates 页面上,确保选择 Create a plug-in
using one of the templates。
在 Available Templates 列表中选择 Plug-in
with Patterns ,然后单击 Finish(图 5)。
图 5. Plug-in with Patterns
模板
在此,Rational Software Architect 将提供一个包含空
Pattern Library 的新插件项目。如果您没有位于 Plug-in Development Environment
透视图中,Rational Software Architect 将提示您切换。此外, Pattern
Authoring 视图,如图 6 所示,添加到了透视图中。
图 6. Pattern Authoring
视图
花些时间浏览 Package Explorer 视图中找到的内容(图
7)。
Activator 类是插件项目公共的,并且由基于 Eclipse 的环境用来与插件交互。
PatternLibrary.java 类是 UML 模式所特有的。在这种情况下,像名字所表示的,它用于表示模式库。如前面所讨论的,模式库包含一个或多个相关的模式。
图 7. Package Explorer
视图
现在您有了空的模式库,那么您需要向该库添加一个或多个模式。向库添加模式的过程如下:
在 Pattern Authoring 视图中,选择 com.ibm.mypatternlibrary
节点。
单击右键并选择 New Pattern。
在 New Pattern 向导的第一页上,为模式提供服务供应者的名称。
提示:
模式的一个关键方面是它有许多表示模式的可变点的参数。这意味着,您可以通过将来自您的模型的元素与参数连接(绑定)来向模式应用添加定制的信息。模式将使用该信息来生成模式解决方案的定制的实例。
要添加参数,单击 Parameters 字段旁边的 Add(图 8)。
图 8. 向模式添加参数
对于第一个参数,指定 Service Provider Name。
对于 Type,单击 Browse,并选择 Literal String
单击 OK 接受类型(图 9)。
图 9. 参数说明
通过这些步骤,您已经指定了,您的模式将拥有一个名为 Service Provider
Name 的参数,类型是 Literal String,多重性为 1 (一)。
单击 OK 完成该参数。
您需要添加更多的参数,因此再次单击 Add。
指定 Service Specifications 为 Name。
将 Type 设置为 Interface。
设置 Multiplicity 为:1..*。(参见图 10)。
图 10. 添加另一个参数
对于该参数您还有一些事情要做。就此模式而言,两个参数之间存在依赖性。也就是,在模式执行其期望的行为之前(举例来说,更新模型元素或添加模型元素),需要来自另一个参数的信息。同样,您需要指定细节来支持该依赖性。
切换到 Parameter Dependency 选项卡。
在 Existing Parameters 区域,选择 Service
Provider Name 参数,然后单击 Supplier Parameters 部分旁边的 >(右箭头)按钮(图
11)。
图 11. Pattern Dependency
选项卡
单击 OK 来完成您对该参数的处理。
提示:
就像您之前可能注意到的一样,当我们观察 Pattern Explorer
视图时,设计模式库(Design Pattern library)有许多进一步将模式分组的子文件夹。库中的这些子分类称为分组。新的模式默认添加到名为
Miscellaneous Patterns 的组中。使用 Groups 字段旁边的 Add 和 Remove
按钮来去掉默认的组并且添加您自己的定制的组。
审查与模式相关的细节,然后单击 OK。
图 12. 定制模式组
Rational Software Architect 向项目添加类。在
Pattern Authoring 视图中(图 13),您将看到您的库现在包含一个模式。
图 13. Pattern Authoring
视图中的 Pattern Library
既然您定义了您的模式的基本结构,那么您就可以定义与模式相关的行为了。在
Package Explorer 视图中,您将看到名为 ServiceProvider 的新类已经被添加到项目中。正如所料,该类用于表示您的模式。让我们来看看该类的细节(图
14)。
图 14. ServiceProvider
类
注意到,在 ServiceProvider 模式类中,有为每个参数创建的内部类:ServiceProviderName
和 ServiceSpecifications。对于每个内部类,有两个一般的方法。
第一个方法, expand(PatternParameterValue
value),当模式的用户将一个模型元素与参数连接(绑定)时调用该方法。
第二个方法,expand(PatternParameterValue.Removed
value),当用户去掉连接,或解开参数时调用该方法。
您将回忆起,我们指定过,这两个参数之间存在依赖性关系。要支持该依赖性,向
ServiceSpecifications 添加名为 ServiceSpecifications_ServiceProviderNameDependency
的内部类。在此内部类之中,有一个特殊的方法:update(PatternParameterValue,
PatternParameterValue)。当元素已经绑定到 Service Provider Name
参数上,并且您将元素绑定到 ServiceSpecifications 参数上时调用该方法。更新和展开方法是模式的重要方法。那些是您将要书写为模式提供行为的代码的区域。在这种情况下,您只需要在满足依赖性条件时指定行为,因此,我们将着重于
update 方法。当为模式撰写代码时,您可以利用这些应用程序编程接口(application programming
interfaces,APIs):
UML 2 API:根据 Eclipse.org:“Eclipse Tools
子项目,UML2 是对于 Eclipse 平台的 UML 2 元模型的基于 EMF 的实现。该项目的目标是提供支持建模工具的开发的
UML 元模型的可用的实现,提供简化语义模型的交换的公共的 XMI 方案,提供作为规范确认手段的测试用例,以及提供作为法规遵循级别的定义和实施的手段的确认规则。”Rational
Software Architect V7 支持 Object Management Group(OMG)UML
2.1 规范的最终版本。
Patterns API:IBM Rational Patterns
Framework API 补充了我们介绍的模式编写功能,并且支持将模式应用于 UML 模型。关于这些
API 的更多信息可以在 Help 系统中找到(图 15)。
图 15. Help 系统
如前面所讨论的,根据用户提供的参数(名称和接口集合),您需要创建 UML
组件,以及组件所拥有的对于服务供应者的 UML 端口。要这样做,您将为 ServiceSpecifications::ServiceSpecifications_ServiceProviderNameDependency::
update(PatternParameterValue, PatternParameterValue)
方法书写代码。用清单 1 中显示的代码来替换该方法中的代码。
清单 1
public boolean update(PatternParameterValue value, PatternParameterValue dependencyValue) {
// We create a component with the name specified
by the service
// provider name parameter (dependencyValue).
// Then, we add a port to the existing or newly
created
// component for each of the interfaces (value).
// If not already applied, we apply the service
profile to the
// model.
// Finally, we apply the serviceProvider stereotype
to the
// component and the serviceSpecification stereotype
to the
// interface (if not already applied).
// Get the value of the first pattern parameter:
the
// StringExpression for the name of the service
provider
LiteralString stringExp = (LiteralString) dependencyValue.getValue();
// Get the value of the newly added element to
the second
// pattern parameter: the service interface
Interface theInterface = (Interface) value.getValue();
// Get the package for the interface, and create
a component in
// the same package
Package pck = theInterface.getPackage();
// Check whether the service profile is applied
to the model -
// if it is not yet applied, then do so
Profile pf = pck.getModel().getAppliedProfile("Software
Services Profile");
if (pf == null) {
// Do nothing
} else {
// get or create the component as necessary
Component serviceProvider =
(Component) pck.getPackagedElement(stringExp.getName(),
false, UMLPackage.eINSTANCE.getComponent(), true);
// Apply service provider stereotype to the
component
String serviceProviderStereotypeName = "Software
Services Profile::ServiceProvider";
Stereotype serviceProviderStereotype =
serviceProvider.getAppliedStereotype(serviceProviderStereotypeName);
if (serviceProviderStereotype == null) {
serviceProviderStereotype =
serviceProvider.getApplicableStereotype(serviceProviderStereotypeName);
serviceProvider.applyStereotype(serviceProviderStereotype);
}
// Apply the service specification stereotype
to the
// interface
String serviceSpecificationStereotypeName =
"Software Services Profile::ServiceSpecification";
Stereotype serviceSpecificationStereotype =
theInterface.getAppliedStereotype(serviceSpecificationStereotypeName);
if (serviceSpecificationStereotype == null) {
serviceSpecificationStereotype =
theInterface.getApplicableStereotype(serviceSpecificationStereotypeName);
theInterface.applyStereotype(serviceSpecificationStereotype);
}
// Create a port on the component, typed with
the interface
Port thePort =
serviceProvider.createOwnedPort(theInterface.getName(),
theInterface);
// Apply the service stereotype to the port
thePort.applyStereotype
(thePort.getApplicableStereotype("Software
Services Profile::Service"));
}
return true;
} |
阅读代码和注释,看看我们如何使用 UML2 API 来执行模型增加的。
提示:
要使得代码更易读,在编辑器中单击右键并选择 Source > Format。当添加代码的时候,添加适当的导入语句。要这样做,在编辑器中单击右键并选择
Source > Organize Imports (CTLR + Shift + O)。确保添加了清单
2 中的导入语句。
清单 2
import org.eclipse.uml2.uml.Component; import org.eclipse.uml2.uml.Interface; import org.eclipse.uml2.uml.LiteralString; import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.Port; import org.eclipse.uml2.uml.Profile; import org.eclipse.uml2.uml.Stereotype; import org.eclipse.uml2.uml.UMLPackage; |
提示:
Organize Import 向导可能自动地错误地分辨一些导入。因此,您需要查看导入列表,并且确保包含了清单
2 中的那些。
选择 File > Save All。
测试模式实现
要测试模式,您需要将模式部署到 Rational Software Architect
的实例上。插件开发环境支持该任务,使您能够启动另一个称为 runtime workbench(运行时工作平台)
的实例。在运行时工作平台中,您将像最终用户那样与模式交互。就像对任何其他的基于 Eclipse 的插件一样,在模式运行时,您可以设置断点,浏览代码,并且更新代码。
首先,在 Package Explorer 视图中,双击打开 plugin.xml
文件。
然后单击 Manifest 编辑器的 Overview 选项卡。
接下来,单击标签为 Launch an Eclipse application
的链接(图 16)。
提示:
要使用断点,并浏览代码,您需要单击 Launch an Eclipse
Application in Debug mode。
图 16. Launch an Eclipse
Application in Debug mode
在此,Rational Software Architect 的第二个实例将启动。在工作平台的运行时实例中,创建新的
UML 项目,然后添加使用了 Blank Model 模板的新的 UML 模型:
选择 File > New > Project。
在 New Project 向导中,选择 UML Project 并单击
Next。
指定 Service Provider Test 为项目名称,并单击
Next。
确保在 Templates 下选择了 Blank Model ,然后选择
Class Diagram 作为 Default diagram type。
单击 Finish。如果提示切换到 Modeling 透视图就单击 Yes。
您现在应该位于 Modeling 透视图中。已经创建了新的 UML 项目,并且它包含了您将要用来测试模式的
UML 模型。
接下来,向 Blank Model 应用 Software Services
概要文件:
确保在 Project Explorer 视图下选择了 Blank Model,选择
Properties 视图下的 Profiles 选项卡。
单击 Add Profile,然后选择 Software Services
under Deployed Profiles 并单击 OK。
接下来,打开 Pattern Explorer 视图。
选择 Window > Show View > Other。
在 Filter 字段中输入模式,选择 Pattern Explorer,并单击
OK(图 17)。
图 17. Pattern Explorer
视图
在 Pattern Explorer 视图下,展开 Miscellaneous
Patterns。您应该看到您创建的模式:Service Provider(图 18)。
图 18. Service Provider
模式
将 Service Provider 模式拖拽到 Main 图上(图
19)。
图 19. 将模式拖拽到 Main 图上
在模型下创建了 Service Provider 模式的新实例。注意到模式实例表示为带有关键字
<<Pattern Instance>> 的 UML 协作。
测试 Service Provider 模式
现在您将测试 Service Provider 模式。
首先,使用选项板或动作栏,在您的模型中创建一些接口:
AccountVerification
AccountActivation
您将使用这些来绑定模式的 Service Specifications
参数。
开始设置服务供应者的名称(绑定 Service Provider Name
参数):
将光标放在模式实例的 Service Provider Name 参数上。
当动作栏弹出时,单击第二个图标(参见图 20)。
图 20. 单击动作栏上的第二个图标
输入 SalesMgr,然后按下 Enter。现在绑定了第一个参数(参见图
21)。
图 21. 绑定第一个参数
接下来,将 AccountVerification 接口拖拽到 Service
Specifications 参数上(图 22)。
图 22. 将 AccountVerification
接口拖拽到 Service Specifications 参数上
这是您为 ServiceProvider::ServiceSpecifications::update(PatternParameterValue,
PatternParameterValue) 方法书写的代码运行的时候。代码生成了名为 SalesMgr
的 UML 组件,以及原型 <<serviceProvider>>。名为 AccountVerification
的 UML 端口,类型为 AccountVerification 接口,原型为 <<service>>,也应该生成于该组件之下。此外,<<serviceSpecification>>
原型也应该应用于 AccountVerification 接口(图 23)。
图 23. Project Explorer
视图中的结果
现在将 AccountActivation 接口拖拽到 Service
Specifications 参数上。观察绑定到模型上的模式实例的结果(图 24)。
图 24. 绑定到模型上的模式实例的结果
您可以将 SalesMgr 服务供应者拖拽到图上,现在应该如图 25。
图 25. SalesMgr 服务供应者的
Diagram 视图
注意,举例来说,SalesMgr 组件(服务供应者)的提供的接口间隔之下的两个
UML 接口(服务规范)。
现在,在外部视图下显示组件:
确保在图中选择了 SalesMgr 组件,单击右键并选择 Filters
> Show External View。
重新安排组件和端口的大小,以便您看到的如图 26。
图 26. SalesMgr 组件的外部视图
在组件上(服务供应者),两个方形是其端口(服务),棒棒糖是为端口所提供的接口(服务规范)。
这些操作完成了您的模式实现的测试。您可以保存您的模型并且关闭运行时工作平台。当您完成了资产的测试之后,您可以将其打包为
RAS(Reusable Asset Specification)进行复用。我们将在本系列后面的部分中介绍资产的打包
什么时候使用模式,以及为什么
本教程介绍了基于模式的工程术语,然后着重于称为 UML 模式的模式实现类型。很重要的要记住的是您构建的
UML 模式不局限于一种具体的模型类型。在您的建模工作中,您可以创建并使用 UML 模式,因为它们可以用在所有抽象层次上。就像在您喜爱的在线书商或技术
Web 站点上搜索到的一样,您可以找到不同类型的模式。对于 SOA 解决方案来说,不论您什么时候需要完成下面这些任务时,您都可以应用
UML 模式:
对候选的服务建模
创建初始的服务设计
精炼您的服务
实施最佳实践
应用复现的解决方案
补偿专家的短缺
当您想要在 SOA 设计中应用最佳实践时是特别有效的。您可以使用在别处定义的最佳实践,以及那些您自己的组织所依据的最佳实践。
这些自动化特性使您能够提高生产力,实施架构完整性,并提高解决方案的质量。我们还期望您将会看到,该过程中的一个关键的步骤是最佳实践的辨别和指定。自动化和编码是简单的部分。价值是获取专家经验、经验,和最佳实践,并且跨团队利用它们。虽然仅仅使用规范就可以成为可能,但是您将会发现,在缺少自动化支持的情况下,让团队获得相同水平的生产力、质量,以及遵守架构的构想是困难得多的。
在本系列教程的第 3 和第 4 部分中,您将看到如何构建转换来支持抽象层次见的转移,以及如何将资产打包用于复用。
|