级别: 初级 Alan W. Brown, 杰出工程师 Jim Conallen, IP 开发
2005 年 7 月 05 日 本文来自于 Rational Edge:在过去的两年里,人们广泛地探讨模型驱动设计在提高生产率和企业应用程序开发质量方面的作用,但是有关 MDA 式样开发的使用方面的经验的书面材料是很少的。本文提供了一组来自 IBM MDA 工具包的设计和使用方面的实践经验。它强调了来自具体 MDA 实践的主要经验,并提供了一些对 MDA 方法的观察,包括对以后工作的简要讨论。
从理论上说,软件开发是一个理解、发现和设计的迭代过程。利用迭代和增量开发技术开发应用程序增加了我们对创建软件系统所能解决的问题的理解。我们利用该理解来为一组确定了的涉众设计并交付他们所关心的解决方案。在整个流程过程中,要获取、分析、细化并传达许多不同种类的信息。由建模技术和工具所支持的模型能够帮助实现该流程。
统一建模语言(Unified Modeling Language,UML)是对密集的软件系统的标准建模标记法。
1
十年前,最初将其设想为当时最成功的建模思想的集合,现在 UML 得到了广泛地应用,并由超过十二个不同产品来支持。通过取决于目标管理组织(Object Management Group,OMG)的标准流程来管理它的发展。
UML 成功的其中一个原因是它的灵活性。它帮助软件开发团队创建一组表现问题域和解决方案域的模型。UML 能够捕获并关联这些领域的多种观点,它能够在不同的抽象级别上进行系统建模,并促使模型分割成用于共享和迭代开发方法所必需的易于管理的部分。另外,模型单元间的关系能够保持在建模观点和抽象级别上,并且可以通过内嵌的 UML 扩展机制将专门的语义设置到模型单元上。(例如,绑定到 UML profile 中的原型和标记值)。
因此,UML 经常作为能够促进以模型为中心的开发的系统和软件设计方法的基础。UML 的用户可以利用非常确实的方法来进行建模,这些方法能够提供一组用于创建、展开并细化由 UML 描述的模型的最佳实践。最有名的是 IBM Rational Unified Process,或 RUP。RUP 描述了一个可以帮助企业成功地应用模型驱动开发(model-driven development,MDD)方法的开发过程。
2
它为模型的创建、发展和维护引入了重要的实践技术,着眼于专业人员团队如何能够进行大规模开发工作可以减少项目中的技术和开发风险,创作出高置信度的模型,并确保不同模型可以适当地同步。
在一段时间里,一些组织已经成功地在基于 RUP 的最佳实践中运用了 UML。调查显示,几乎 40% 的开发人员使用某种基于 UML 的建模方法,及支持 UML 的引导市场的工具,IBM Rational Rose 的累计销售量已经超过 25 万。
3
随着对这些模型投资的增加,一些组织已经开始将许多 MDD 方法的模型转换方面进行自动化。实际上,他们已经组合使用了 UML、RUP 和 Rose 作为一个平台,在该平台上建立他们自己的模型驱动方法——书写 RoseScript 以在 IBM Rational Rose 中控制模型,或者建立用于控制由 IBM Rational Rose 通过可扩展标记语言(eXtensible Markup Language,XML)模型互换格式(eXtensible Markup Language Model Interchange format,XMI)具体化了的模型的外部实用程序。有时候,用户会重点投入到这些层,作为获取他们组织建模和模型转换最佳实践的途径。
OMG 已经将解决 MDD 的详细方法标准化。由 OMG 定义的模型驱动体系结构(MDA)概念着重于利用 UML 创建模型,以及在不同的抽象级别间对这些模型进行转换。这将导致支持创建、管理和共享这种转换的产品的出现。商业产品(如 Codagen 和 arcStyler)和开源成果(如 AndroMDA 和 OpenMDX)扩充了建模工具(如 IBM Rational Rose)的功能,以支持 MDA,并简化了这些转换的创建、管理和应用。
4
在本文的第一部分(发表于 2004 年 2 月的 Rational Edge )中,我们讨论了如何将建模应用到当今的行业中,以及 MDA 与现今系统的相关性。在此,第二部分中,我们将用这种设计并使用 IBM 的 MDA 工具包的观点来检验模型驱动开发的方法。我们将描述该工具的基本原理,探究它的重要功能,并强调许多重要的经验,这些经验是关于在许多定制环境下应用和利用基于对 MDA 工具的使用的模型驱动开发。在下个月出版的第三部分中,我们将讨论关于 MDA 方法的传统软件生命周期实践的适用性,并对实践中模型驱动方法的成功应用进行全面的观察。在整篇文章中,我们假定您熟悉 OMG 的 MDA 方法,并设想了一个利用 UML 建模的背景。其他地方有许多对这些主题的介绍。
IBM Rational XDE Java 的 MDA 工具包(MDA Toolkit)
随着 IBM Rational XDE 2002(即 IBM Rational 的下一代建模环境)的引入,为模型驱动式样的开发提供适当的支持是很重要的。由于它的引入,用来在 IBM Rational XDE 中创造定制的自动化的主要机制已经成为可执行的模式的机制。该机制允许开发人员将可执行的模式创建并设计成可视化的模型。模式开发人员利用 IBM Rational XDE 在“模式”单元中创建图表和模型单元。该模式(本身为定型的 UML 模型单元)能够在模型的其他部分或其他模型中执行。该机制从本质上使得目标模型的指定部分看起来如同模式。
该类型的转换引擎本身就涉及了一个说明性的式样。就是说,在图表中,构成了模型单元的结构。那些单元的要素和属性是参数化的。有特别标注的代码能够表示模式中的条件性及程序性的单元。这些标注能够简单地调回模式执行的特殊步骤中所执行的方法。
早期的问题和结论
我们最初想要利用模式机制来实现大规模 MDA 式样的转换的尝试是令人失望的,整个模型是通过一批操作来进行处理的。然而,我们在实践中发现的执行中所经历的完整功能会导致转换的复杂度增加。这使得我们提出新的主张,(尽管对它们的定义及理解相对简单)即说明性式样的转换机制(如 IBM Rational XDE 中的可执行的模式机制)不适于我们试图建立的大规模的 MDA 式样的转换。
我们推断,模式机制能够良好地适应于对离散的、单个选择的模型单元进行小范围的转换。当转换映射主要是说明性的时,模式也会是最有效的。转换映射的算法复杂度越高,它就越不适应于可视化的、可执行的模式机制。我们所需要的是更具伸缩性的方法来实现 MDA 式样的转换、一个能够处理不断增长的算法复杂度的方法,并且能够伸缩到支持涉及大型模型的转换。
这些推动因素导致了 IBM Rational XDE Java 的 MDA 工具包的生成。该工具包主要的目标是使得开发使用并操作由 IBM Rational XDE 生成的 UML 模型的大规模 MDA 式样的转换成为实际。
MDA 工具包的关键方面
IBM Rational XDE Java 的 MDA 工具包为转换程序设计者提供了框架以开发并部署包括 UML 模型的 MDA 式样的转换。
5
生成工具包的转换本身是程序性的,由于它们在很大程度上是 Java 代码。不同于可视化的可执行模式的机制,创建 MDA 工具转换的大部分工作依赖于撰写能够直接操纵模型和其他参与转换的工件的代码。此种转换开发的方法对于处理任意算法复杂度的转换映射来说是简单有效率的。
该工具包提供了特殊的应用程序设计接口(application programming interface,API),建立在能够提供众多 MDA 转换中一般特性的基本模型访问 API 之上。大多数 UML 模型 API 仅仅提供了最基础的模型访问功能(获取、创造及更新模型单元或属性)。当开发涉及到 UML 模型处理的 MDA 转换时,额外的更高级别的功能是令各种转换能够坚固、可伸缩并可维护的关键,这已经成为一种经验了。MDA 工具包提供了包含高级功能的用于模型访问的 API(MDA API),例如:
-
智能地且深度地复制模型单元。复制模型单元(尤其是当单元为容器时,或者当它们与容器外部的其他单元相关时)需要进行许多分别的判定。复制方法的可选参数确定如何复制关系和子单元。可以复制两端连有单元的关系,或者在复制一端而固定另一端(例如,连接了共享的框架对象的关系)。工具包的“智能复制”方法提供了帮助解析名称的回调机制。
-
具体语言的行为。用来进行单元比较的技术,如名称或操作签名,可以随着目标语言而变化。例如,在不同的目标程序设计语言中,一种搜寻或创建指定的模型单元的操作需要由一种具体的目标语言技术来处理大小写字母。同样地,当对具体语言(如 C++ 或 Java)的操作进行比较时,单独用操作名称就不够了,在这种情况下,通过操作的签名进行比较,这样仅需识别参数类型的列表,不识别名称和返回值。使用于模型访问的 API 能够被理解并按照规则运行的功能可以令模型的使用变得非常简单。
MDA API 的本质设计目标是在支持重复转换调用思想的 API 中开发固有的行为。我们已经发现,在重复开发流程中会进行可重复多次的转换,在这样的流程中会大量使用 MDA 转换。因此,非常关键的是任何由转换修改了的部件会保存所有并非直接联系到转换的原始单元的信息。例如,一个将抽象的 UML 类转变成 Java 类的转换(在此种情况下源文件已经存在并且包含许多帮助属性和方法)不应该在重复的转换过程中删除现有的代码。
UML profile的任务
MDA 工具包中包含有可以创建并刷新 UML profile的工具。我们发现,在大多数涉及了 UML 模型的转换中会使用到定制的 UML profile。在典型的 MDA 转换中,profile启到了两个不同的作用。这些profile可以是 语义profile,它们能够令模型准确恰当地获取并表达具体的信息。这是对 UML profile的典型使用:定义一组解释某个模型的语义。然而,还可以将它们用作标记机制。在 OMG MDA 术语中,标记一个模型意味着利用工具所使用的,不适合从模型的语义中得到的额外信息来标记一个模型。该信息不是模型内容本身的抽象级别领域内的信息,而是在自动的转换过程中所必须的信息。
该工具包含有一个编辑和运行时组件。编辑组件可以进行 UML profile的创建,并且包含项目创建的向导(带有示例代码)。只有在那些创建定制的 MDA 转换的工作站上才需要编辑组件。运行时包含 MDA API,这些 API 可以在基础模型访问 API 上提供高级别的 MDA 功能,且是每个涉及 MDA 转换的机器所需要的共享组件。
封装并传递 MDA 工具转换
由工具包所创建的转换被封装成 Eclipse 插件,这样可以使开发好的转换很容易地部署到开发团队中。工具包将转换开发人员与创建 Eclipse 插件的细节隔离开,所以开发人员可以专著于转换本身的开发。
工具包管理着大部分 Eclipse 插件项目的细节,包括用户界面和缓冲的参数选择,因而可以解放转换的开发人员从而专注于实际的转换逻辑的实现工作上来。一旦一个转换和任意所需的定制的 UML profile生成后并准备用于部署,它们将被封装成 Eclipse 特性并出现在内部的内联网或 Web 站点上。每个开发人员会安装想要的转换和独立的插件。一旦安装了这些内容,开发人员会看到一个新的菜单项及一组默认的参数选择,在调用转换本身之前,开发人员能够看到所需参数的提示。
映射中所有的详细转换逻辑都是在下载了的转换中进行的编码并与其一起执行的。仅仅这样不足以确保能够正确地使用任意给出的转换。因此,大部分构建良好的转换将包含添加到 Eclipse 在线帮助上的新部分。这些部分应当描述什么时间、为什么,以及如何调用转换。当然,在每一个将要引入自动化的环境中,都应当对流程进行更新并进行传达。
IBM Rational XDE Java 的 MDA 工具包出现于 2003 年下半年,并且应用于各种各样的客户环境中。我们在工具包的设计和应用上的经验补充了我们早期的工作,并为那些对 MDA 实践应用感兴趣的人总结出的许多关键的经验。
关于 MDA 解决方案的设计和应用的经验
在过去的几年内,许多企业使用了模型驱动开发,包括对模型转换的使用。实际上,本文的作者直接或间接地涉及了对大规模系统的模型开发、模型转换的建立、MDA 工具的设计,和在若干客户环境中对 MDA 工具的使用。因此,可以根据这些经验开始细化一组开发 MDA 式样的解决方案的最佳实践。
虽然每个用户环境都有自己的关注点,但是我们相信在创建 MDA 解决方案时应当一贯地按照下面的步骤进行:
- 检查当前开发流程中所使用的模型,以及抽象边界上单元之间的语义连接。
- 为自动操作识别候选的转换。
- 指定(编制)转换需求。
- 创建必要的 UML profile。
- 开发转换代码。
- 起草使用文档,并封装部署。
这些步骤形成了各种 MDA 项目的基础,当外加上典型的重复设计和削减风险的开发实践时,这些步骤会为 MDA 方法提供健壮的指导。最重要的是,从我们对这些步骤应用的经验来看,我们可以细化出一组能够为那些 MDA 的实践提供经验教训的试探法。我们现在将具体审视那些经验教训。
语义模型连接
经验 1. 仅在充分理解了模型单元之间的语义连接后才进行转换的开发。
在将自动化引入到开发流程中之前,您必须对流程中使用并管理的所有模型进行完全彻底地了解。开发工作经常开始于无用的模型,这仅仅是因为它们所需要的不适合的开发流程或方法状态。除非在软件项目过程中,正在进行开发的模型为工作提供清晰有用的信息,否则就不应该创建或维护模型。另一方面,许多项目经常缺少一些重要的,连接系统各部分的模型和抽象。很明显,只要在工程的特别部分中运用大量的人工解释和创造,那么就可能需要能够获取思维过程和在那些活动中所做出的设计决策的正式模型。
抽象边界上模型中单元之间的语义连接对 MDA 的环境是特别感兴趣的。今天围绕 MDA 的大多数实践活动涉及了模型转换的自动化,特别是那些在更高的抽象级别之上的模型和更低的抽象级别之上的模型间的特殊的转换。具有代表性地是,像此“散开”的连接,更确切地说,一个高抽象级别上的单个模型单元(如,用例)连接到多个低抽象级别模型中的模型单元(如,边界、实体和控制器)上。
这些连接的可溯性因一些原因而变得很重要,最重要的原因是支持自动的转换。除此之外,在重复的开发环境(任何转换都可能被多次调用)中,它也具有重要的意义。在我们的经历中,一个转换很少是简单地将信息从一个输入模型移动到一个输出模型。更具代表性的是,存在一个主要的输入源,以及一些额外的通用参数和一组输出模型。例如,在一个典型的 J2EE 系统中,一个分析模型含有转换为数据库设计、Java 接口和对象设计、一组 Java ServerPage(JSP)和许多配置或部署描述符的信息。所有这些更详细的模型应该保持同步以适当地执行。因此,往往最方便的做法是开发一个单个的转换,让它管理从主要的高级源模型到低级模型的信息转换,以代替为每个输入和输出模型的组合开发单独的转换。这种功能就是在各种低级模型上调整语义内容,该功能使 MDA 成为具有吸引力的技术。
此外,在本情境中转换的重要属性是开发人员所具有的能够更新那些直接依赖于上游模型的下游模型的单元的能力。任何从详细的模型中获得的不是由转换首先生成的附加信息应当保持原样。另外,由转换创建的模型单元不应该在调用过程中的下游模型中进行复制,只能够对它们进行更新(或者在模型中不存在的情况下进行创建)。MDA 工具包 API 的构成使得转换能够固有地依照这些设计原则。
识别候选的转换
经验 2. 并非所有的语义连接都导致好的 MDA 转换。
当识别出模型中单元间紧密的语义连接时,应当对它们进行检查,看看治理着它们关系的规则是否适合于自动化。当这些规则是清楚并且明确的时候,才能够对这些适当的转换进行实现。它们可能是大的且复杂的,或者琐碎简单的,不论哪种状况,都适合撰写一个转换来实现它们。然而,如果这些规则定义了这些连接,随后,用来在其他模型中构建新的单元的原则将需要开发人员的经历和判断力,然后才能够轻易地排除自动化。
另一个去掉自动化的原因是缺少计划性地访问模型本身必要的单元的能力。例如,大部分涉及自然语言文档的阅读的转换步骤(不管它们中形式的级别),不适合 MDA 式样的自动化。我们常常发现,将用例规范文档转换成分析模型通常是不实际的。 然而,转换一个伴随着用例的 UML 顺序图或者活动,可能适用于自动化(构造非常严格)。
编制转换需求
经验 3. 应将 MDA 转换的撰写视为软件开发项目本身。
最有用的转换是将那些对于大多数开发人员来说或者冗长或者复杂的难于一贯地且可靠地进行实现的工作自动化。MDA 自动化能够确保一致性,并在大多数情况下节省时间。令人惊奇的是,最成功的转换实际上是不平凡的软件的实例。当您在考虑 MDA 自动化的使用及不平凡转换的创建时,您应该将此视为独立的软件开发。
一个转换,特别是由 MDA 工具包创建的转换,是一个定制软件的实例。应当清楚地了解需求,并在语义上的和技术上对需求进行核对(参见经验 1)。 大多数需求规范都包含于映射文档中。映射文档详细描述了参与到转换之中的各种模型中的建模单元之间的语义连接。其他相关需求可能包含性能、安全和可伸缩性等。
我们涉及的大多数转换由许多类来进行实现,因此,要经历一个分析和设计阶段。其他实践问题,如测试、部署和培训也具有和典型软件开发流程的相似之处。尽管最典型的 MDA 转换不需要很大团队来实现,但是将它们视为独立的软件开发工作将确保完整性和质量。
当指定了用 MDA 工具包实现的转换的需求时,您应该考虑三个截然不同的行为:
- 检验输入参数(和内容)的有效性,看看是否为必要的且一致的信息
- 执行核心转换逻辑或映射
- 验证参与转换的模型单元间的语义连接
转换逻辑的执行和下游模型的修改是整个转换中最重要的工作。然而,在迭代开发环境中,有效的输入和成功完成的验证也是很重要的。
经验 4. 在转换执行前,确保参与其中的所有参数和工件的完整性。
虽然可以在 MDA 工具包创建的转换中调用并执行任何东西,但是还是不存在固有的事务流程控制。在一种转换开始,但在完成前中止的情况下,没有设备可以保证该情况将导致所有输入参数重新设置成先前的状态。这是因为 MDA 工具包没有限制参与到转换中的工件的类型。转换很有可能调用外部的 Web 服务或者永久地改变工件。
由转换开发人员确保转换中控制的工件的完整性是普遍的。所以,有必要在转换发生之前确保工件输入集的状态(例如,所有必需的参数都得到了指定,所要求的profile应用到了模型中,且模型中所要求的内容是核对了的工件)是已知的。在转换执行了一段很长的时间(如果转换特别复杂或者依赖于大量资源的话,转换执行几个小时的时间是很平常的)时,这样做也是有用的。如果能在早期就确定参数(或者任意参与进来的工件)的无效性,就能够节省用户的时间并保持工件的完整性。
经验 5. 依据下游的变更,要维持转换的完整性就需要一个验证规范。
当转换成为迭代开发过程的一部分时,甚至很可能在转换执行之后,输入和输出工件都将由人工更新。这遵循了模型驱动开发的普遍原理:在适当的抽象级别(不管是什么样的抽象级别)上,将变更首次引入到模型中的系统里。例如,由高级分析模型描述的 Customer 实体可能不包含关于持续策略的信息(乐观的、悲观的,等等)。所以不需要将对该策略的变更引入到分析模型中,而是引入到设计模型中,在该模型中变更所产生的影响最大。因此,为 Customer 类增加一个新的关键属性可能需要直接对高级别分析模型进行变更。当条件适当,且进行了可能的评估之后,将这些变更映射到自动化的 MDA 变更结果上可能会与将变更映射到低级模型上一样合适。
因为迭代开发过程会促进贯穿开发过程中的模型的发展,所以一个良好的自动转换的重要特性是具有能够分析工件当前状态并且将工件比作想要的东西(如果变更将和这些工件一起执行)的功能。在 MDA 工具包的转换中,该步骤应与一个单独的且独特的验证步骤同时进行。当对下游工件进行变更,和随后的修改之后,再单独执行验证步骤。在特有的情境下,开发人员可能会利用转换来更新或创建一组带有抽象模型中所包含的新的信息的模型或代码。然后,可能对那些下游的模型和工件进行更进一步的细分,这些细分与转换流程所管理的语义信息不相关。在细分的过程中,可能会打断预期的模型间语义连接的变更(尽管不希望出现)。转换的验证步骤将为开发人员生成一个报告,其中包含原始转换所形成的语义映射中的间断。开发人员可能会恰当地处理,并会对上游模型、下游模型或者两者都进行变更。
经验 6. 在大部分 MDA 环境中,模型到模型的映射是很复杂的,并且需要进行仔细的设计和实现。
转换的核心逻辑经常能够表现为一个算法,该算法的功能是将一组模型单元转变为另一组。在简单的说明式映射中,连接是相当的简单、直接,且明确的。在我们所见到的大多数大规模的 MDA 式的转换中,映射并不总是那么简单的。下游模型中的单元常常会在一组复杂的条件(该条件会涉及到其他下游模型单元、连接和原是模型及各种 UML profile的标记值)下映射到一个单元的结构上。
举一个简单的例子,有一个持久稳定的实体称为 Address,它定义了许多属性,其中一种标记为(标记profile中的)键码类型。将类似这样的抽象类映射到 Java 对象和数据库设计上是相当的简单的(参看图 1)。图中表明生成了一个 Java 对象,同时对属性进行了镜像,并校正了数据类型。同时还生成了获得方法和设置方法。在数据库设计中,生成了一个表,以及拥有适合企业标准的名称的列。 并设置了主键(通过标记profile中的标签进行识别)。标记profile还可以用作确定空和其他典型的数据库属性。
图 1:将简单实体映射为对象和数据设计模型
该简单实例说明了将抽象模型中的单个类映射为对象模型中的单个类和数据模型中的单个表。抽象模型中的属性与对象模型中的属性及数据模型中的列一一对应。对象模型中的操作都能够追溯到抽象模型中的一个属性上。但是在另一个实例中,映射就不那么简单了。举第二个例子,一组参与到分析模型层级中的类(图 2)。
图 2:分析模型中的特定化
RestrictedProduct 和 CommericalProduct 类是 Product 的特定化。Product 类也确定了两个属性(代码和供应方),作为对象标识符或键码,但是,通常将其视为标记值或原始模型,可能不会在图表中出现。利用组织的命名约定和属性映射策略,有三种不同的方式将该组类转换成数据库模型。我们将三种基本策略称为“上滚(Roll up)”、“下滚(Roll down)”和“分隔表(Separate Tables)”,IBM Rational XDE 的 Data Modeler 能够支持这三个策略,如图 3 所示。
图 3:上滚一般化策略
在第一个策略中,通过在基类后加上 _TYPE 后缀来创建一个新的表类型。该表的列由映射预定义,并总是保持不变。该“类型”表仅仅用于提供能够简单地添加新类型的可扩展的方法。所有子类的属性能够上滚到一个主表中。
在下滚策略中,如图 4 中所举例,所有的具体类都分配到它们自己的唯一的表中,基类中的列会复制到所有这些表中。
图 4:下滚一般化策略
最后,在分离表策略中,如图 5 中所举例,对所有的类和一张表进行镜像,在基类和其子类间创建识别关系,以便子表中相应的数据行能够访问从基类中获取的属性。
图 5:离表一般化策略
从该实例中可以看出,很明显,映射策略不再简单,并且抽象模型中的一些单元很可能会同时映射到数据库设计中的不同单元。并且在上滚情况下,所有三个分析类会映射到两个表上,其中一个共享了普通名称。
生成的对象模型也需要一个作为对象键码的单个属性(如在 J2EE 中)。图 6 中说明了到 Java 对象模型的转换。因为对象的键码由两个属性组成,所以就生成了一个新的键码类,且除了获取方法和设置方法以外,对象设计中还加入了定向的关联。
图 6. 带有一般化和组合键的 Java 对象设计
甚至这个简单的情境都能说明现实生活中映射的潜在复杂性。按照规则,确定映射策略是否依赖标记值和分析模型配置的组合会更加复杂。(例如,当存在三个或更多类时使用上滚,除非将替换标记值设置为 False,否则将组合键替换为一个自动生成的整数,等等)。
从微观上看,没有什么问题是难于克服的,分别检查每种情况,都能讲的通,还经常符合设计者和开发人员过去手动的工作内容。然而,当集合到一个单独的,需要协调多个下游模型的内容和结构的转换中之后,错综复杂的逻辑经常使得简单的说明式转换都变得很难。在这些情况下,用算法方式能够很好地表示并实现转换,这是 MDA 工具包的模型使用风格。
经验 7. 可以用说明式的或命令式的方式表示转换。一般来说,当描述复杂的转换时,命令式的方法更适合。
尽管 MDA 工具包会很自然地强调用命令的形式来考虑实现,但它还是允许 XDE 模式调用或支持说明性的例程。MDA 工具包能够使转换开发人员创建带有预定义的,可以被有选择地复制到目标模型中,并能够在复制过程中改变的模型单元的参考模型。
图 7 显示了一段包含许多类和关系的参考模型。一些类中含有属性和操作。这些操作拥有与其相关的完整代码模板,这些模板用来生成完整的方法体代码。模型单元的名称是无效的 Java 标识符,因为不需要用这组类来直接生成代码。相反地,这组类将被复制到代码模型中,并在复制的过程中,用出现在转换的输入模型中的真实的类名更新单元的名称。
图 7:参考模型中模型单元的模式
转换的整个过程是处理输入模型(独立于平台的模型 —— 或称为 PIM),并准照标记为 managed class的类。PIM 中的这个标记表明该类应该转换成目标的具体平台模型 —— 或称为 PSM 中的一组类。所以,对于 PIM 中的每个 managed class,图 7 中的一组类将被复制到 PSM 的适当位置,并且在复制的过程中,类名将会随着来自原始 PIM 类中的信息而改变。
图 8 描述了将一个 PIM 中的 managed class 类转换到 PSM 中的结果。转换的结果是生成了四个新类,它们的名称是根据原始的 PIM 类而来。转换不但复制了结构和参考模型段中的属性,而且还适当地根据 PIM 类的属性和操作扩充了新建的类。在 PSM 中还适当地生成了获取方法和设置方法。
图 8:应用基于参考模型的模式
该类型的转换方法利用了说明和图形式样的模式定义进行代码的优先控制。在转换的过程中,回调方法被设置,并在复制过程中被调用。这给开发人员一个机会来指定并精练所有正在复制的单元的目标名称。在创建并复制了参考模型中的信息之后,还要加上由 PIM 类中的所有公共属性和方法复制过来的内容,并创建获得方法和设置方法。
创建 UML profile
经验 8. 作为 MDA 转换的一部分,UML profile可以用来管理模型标记。
UML profile有两种截然不同的用法。第一,UML profile的传统任务是为提供一种机制来为特殊的定义域或方法扩展 UML 的语义。它可以使 UML 能够有效地为具体的内容建模。IBM Rational 的业务建模profile(Business Modeling Profile)和数据建模profile(Data Modeling Profile)就是使 IBM Rational XDE 有效地为业务流程和逻辑或物理的数据库设计建模的 UML profile的实例。对于模型本身要获取并表示有关特别的抽象级别和定义域的细节这件事来说,使用这些类型的profile(作为语义profile)是必要的。
对于管理模型标记(MDA 转换流程中的必要单元)来说,profile也是有用的机制。标记是 MDA 中的一个步骤或技术,在这个步骤当中,附加的信息(不包含在模型本身的语义范围中)能够被加入到模型中,在随后的自动过程中单独使用。通常在准备调用转换之前要进行模型的标记工作。当然,可以在开发模型的时候对它进行标记。然而,创建模型的开发人员没有责任去理解各种标记的意义和用途,且不具备做这件事的技能。
例如,假设一组分析员用 UML 开发了一个简单的抽象实体模型(传统分析模型的一部分)。该模型定义了许多目标系统中的持久不变的实体,包括它们的属性和之间的关系。该信息转换成逻辑的(或物理的)数据库设计。但是当用分析模型创建新的数据库模型时就会出现问题,因为,从分析模型中得来的信息已经不足以完成工作数据模型了。例如,可以将实体的 String 类型的属性实现为 CHAR、VARCHAR 或 TEXT 类型的列。另外,很少能从分析模型中得到列的长度信息。
在进行从高抽象级别的模型到低抽象级别的模型的转换时,经常会遇到信息不足或不全的问题。甚至在将 UML 关联映射到 Java 字段上的时候,对关联中的“many”如何实现都是不清楚的。集合、列表和映射的语义远远超出了大多数 UML 分析模型的语义范围,但对 Java 类的实现是很关键的。
UML profile可以解决这个问题,它提供一个机制,通过这个机制,可以利用转换中用到的信息(即使超出模型的正式语义范围)来扩充模型和模型单元。标记profile(与任何应用的语义概要模型都不同)可以应用到模型上,定义原型和包含仅在转换过程中用到的信息的标记值。数据模型profile可能会包含描述列长度或精度的标签。Java profile可能会包含关于如何在 Java 中实现关联的信息。创建 UML profile的 MDA 工具包功能实际上就是 MDA 转换的一个实例。首先建立一个 UML 模型,复制模型中的类和属性(这些最终用于生成实际的profile),通过这些操作来创建profile。复制profile模型的单元就是用转换中所必要的信息来“标记”模型,从而建立实际的,向 IBM Rational XDE 登记了的,并且随后能够应用到任何 IBM Rational XDE 打开的 UML 模型中的profile。
开发转换
经验 9. 生成的所有转换都应当能够参与到迭代过程中来,并且在重复的应用过程中不丢失独立的信息。
任何转换的关键性设计目标都是该转换是否具有参与到迭代开发流程中的能力。虽然开发一次性的转换会更简单,但是就经验来看,相对于开发这种类型的转换所需的工作量来说,它们的用途是非常少的。相反,能够连续地用于发展开发生命周期工件的转换更值得去开发。
在用 MDA 工具包开发能够参与到迭代开发流程中的转换时,需要注意一下设计和实现过程中的所有单元。可以为模型访问和操作提供主要方法的 MDA API 能够促进该类型转换的开发。例如,当创建某个类的属性时,MdaClass 对象的 createAttribute() 方法首先会默认地核对该属性名是否已经存在。如果该属性已经存在,该方法会简单地返回该属性的实例,不新建该属性的一个副本。有趣的是,这不是大部分 UML 访问 API 的默认动作,因为 UML 规范本身不要求唯一的属性名。因此,理论上,UML API 应该允许。然而,大多数转换的目标都是现时的实现语言,像 Java 或 C++,因此,在实际中,不需要模型 API 中此种类型的动作。
MDA 工具包 API 会有实现误差。在比较类名和属性名时,API 会寻找容器内的单值,并区分大小写。在比较操作的时候,API 会比较名称(区分大小写)以及输入参数数据类型,并忽略返回值类型。因此,对于那些用 Java 或 C++ 语言实现的转换开发人员来说 MDA 工具包 API 会使可重复转换的开发变得非常简单。
开发 MDA 工具包转换的整个流程等同于开发一段 Java 代码,特别是开发一个 Eclipse Java 插件。幸运的是,工具包向导提供了 Eclipse 所需的大部分代码,并让转换开发人员专注于转换逻辑的实现。
经验 10. 好的转换实现了分立的确认、转换和验证程序。
当工具包向导生长一个工程时,向导会为三个关键方法提供部分代码或实例代码,如表 1 所示。
表 1:在转换工程种用到的三个关键方法
这三个方法中最重要的是 transform() 方法,当开发人员要调用所用到的转换时会调用该方法。在该方法中要编写转换的主要逻辑。任何由调用转换的开发人员所指定的参数值可以通过简单的方法调用而获得,并转化为更有意义的东西,如 MDA API 参考。转换的逻辑经常交给帮助方法和其他执行实际的转换工作的定制类来处理。在转换的过程中,讲状态信息写入可视化日志是很有用的,这样开发人员可以控制进展。
在表 2 中显示的实现示例中,指定分析模型和设计模型的文件名作为参数。通过调用父类的方法来访问参数值。这些会转变成 MdaModel 模型的参考。在该实例中,要为定型为“PersistentObject”(在定制profile中),非其他类的子类,的所有类而检查分析模型,由于整个系统都在一个单一的方法中进行了处理。大部分的工作由 processPersistence()帮助方法进行协调,接下来利用若干委托的类来执行大多数转换工作。
表 2:实现示例,在该示例中,为定型为“PersistentObject”的所有类进行检查
在 transform() 方法之前调用 validate() 方法,如果该方法返回假,该方法会中止一切对 transform() 方法的调用。在表 3 中所示的实现示例中,核对分析模型,以确保其的存在以及定制profile已应用到其中。核对设计模型以确保其存在,并且确保其为 IBM Rational XDE 的代码模型,且能够进行反复的工程 Java 代码的开发。
表 3:核对分析模型,确保含有定制的profile,并应用到模型中,核对设计模型,确保其能够进行反复的工程 Java 代码开发。
依据想要的验证级别,verification() 方法会与转换方法本身一样复杂,很显然会使用帮助方法和类似实际转换代码的类。在表 4 中所示的实例中,相同的代码用于识别分析模型中要进行转换的单元。
表 4:方法 verification() 将会使用帮助方法,及类似于实际转换的代码的类。
MDA 转换的开发和测试类似于任何一个 Eclipse 插件工程。使用 Eclipse 运行时工作台(实际上是新启动了一个 Eclipse 及调试模式下的 IBM Rational XDE 外壳)对转换进行调试,并启动对转换代码单步跟踪。
部署转换
检验 11. 使用 Eclipse 插件体系结构极大地简化了安装并升级 MDA 转换的工作。
当开发完一个转换之后,接下来就要对它进行部署,并培训一个很大的开发团队。幸运的是,Eclipse Update Manager 机制提供了便捷的机制将插件安装到 Eclipse 外壳上。利用内嵌的 Eclipse 插件开发环境(Eclipse Plugin Development Environment,PDE)功能,将转换封装,并放置到内部的 HTTP 网站上,开发人员可以简单地从该网站上下载并安装 MDA 工具包转换以及其他相关的插件。
一旦安装到开发人员的工作台上,对应转换的菜单项对任意视图都是激活的。菜单项提示开发人员转换的参数。开发人员可以随意地运行三个方法(确认、转换或验证)或单独运行一个。结果将显示在更新了的模型和工件上,以及日志窗口中。
经验 12. 要对每个 MDA 转换进行很好的描述,提供示例,指导及支持信息。
为开发人员提供转换功能是不够的。不论什么时候,当开发团队得到重要的新功能(如 MDA 转换)之后,还应该教会他们如何使用。由于大多数有价值的转换工作都相当复杂,因而断定,在许多情况下,关于什么时候使用及将什么作为参数的决定可能会同样复杂。
更新开发流程并提供同转换一起的在线文档是必要的。在 Eclipse 环境中,将文档插入到在线帮助的其余部分是很简单的,且作为转换插件本身的一部分,或是一个和转换一同安装的相关插件。
在下个月的第三部分中...
利用 MDA 方法建立解决方案需要对开发流程进行变更。虽然我们从许多用于企业软件开发的现行最佳实践中得来的经验仍旧是可适用的,但是由于具有了更多对开发流程的模型驱动的观点,就需要对那些实践进行变更。要探究该话题,我们将在下个月总结 MDA 的介绍的三个部分,着眼于有名的 Rational Unified Process 上,并考虑对流程的解释方式,以及在 MDA 工程中执行流程的方式。
注释
1参见 J. Rumbaugh, G. Booch, I. Jacobsen,The Unified Modeling Language Reference Manual,Second Edition,Addison-Wesley,2004。
2 参见 P. Kruchten, The Rational Unified Process:An Introduction,Addison-Wesley,1998,和 P. Kroll and P. Kruchten, The Rational Unified Process Made Easy:A Practitioner's Guide to the RUP,Addison-Wesley,2004。
3 依照 Evans Data Corp., North American Development Survey: Volume 1,Response to question on “Use of UML in Application Design,” Fall 2003。
4 要得到这些产品,参看以下 Web 站点:Codagen -- http://www.codagen.com;ArcStyler -- http://www.arcstyler.com;AndroMDA -- http://www.andromda.org;openMDX -- http://www.openmdx.org
5 关于 IBM Rational XDE 的 MDA 工具包的更多细节,包括下载,请访问 http://www.ibm.com/rational/mda/toolkit.html。
参考资料
- 您可以参阅本文在 developerWorks 全球网站上的英文原文。
作者简介  | 
|  | Alan Brown 负责 IBM Rational 桌面产品背后的技术策略工作。他还是负责协调 Rational 工具和组成 IBM 软件开发平台的 IBM 产品的领导团队中的关键成员。另外,他负责为公司的模型驱动开发工具制定前景和策略。
由于对 IBM Rational 桌面产品的贡献,以及对软件行业前途的主要贡献,他赢得了杰出工程师的头衔。在超过十年的时间里,Alan 作为行业思想的引导者,通过他的书籍、论文、以及和 IBM Rational 顶级客户的众多交流来引导开发人员经验的发展。要了解更多他的工作和思想,请访问他的 Web 站点 www.jorvik.com/alanbrown/index.html。
1988 年 Alan Brown 于 Newcastle-upon-Tyne 大学取得博士学位。 |
 | 
|  | Jim Conallen 是 IBM Rational Development Accelerators 小组的软件工程师,他积极地投身到基于资产的开发和可重用的资产规范(Reusable Asset Specification,RAS)的领域中。Jim 经常在会议中演讲,并撰写文章。他研究的领域有 Web 应用程序开发,在该领域中,他开发了 Web 应用程序向 UML 的扩展(Web Application Extension for UML,WAE),即令开发人员在适当的抽象和具体级别上利用 UML 为基于 Web 的体系结构建模。此项工作作为 Rational Rose 和 XDE Web 建模功能的基础。
Jim 已经撰写过书籍 Building Web Applications with UML 的两个版本,第一版着重于微软的 ASP,最近的一版着重于 J2EE 技术。您可以通过 e-mail 联系他。
|
对本文的评价
|