在本文中,使用 Eclipse Modeling Framework (EMF) 和 Graphical Modeling
Framework (GMF) 技术来为领域特定语言产生领域特定建模辅助工具。了解定义领域特定语言的价值,探索基本概念和不同的建模方法,以及获取有关创建良好元模型的提示。
在体系结构设计和软件工程中,您需要清楚理解体系结构的领域,并且能够有效地将该信息传达给其他人员。可以使用各种技术和工具来应对此挑战,例如使用领域特定语言(domain-specific
language,DSL)和领域特定建模(domain-specific modeling,DSM)。DSM 充当 DSL 的前端,并允许用户通过可视化的表示形式来表示构造。
本文集中于使用 Eclipse Modeling Framework (EMF) 和 Graphical Modeling Framework
(GMF) 技术来说明如何为 DSL 产生 DSM 辅助工具。
要使用 EMF 和 GMF 来开发 DSL 和 DSM,您需要以下工具:
- 建模和元模型建模概念和技术
- 使用 EMF 的建模
- 使用 GMF 模型来进行工具开发
- 模型转换概念和技术的建模
- 构件转换概念和技术的建模
- 软件工程和编程:
日常生活中存在许多适用或使用 DSL 的领域。一些实际 DSL 包括:交通和道路标志、平装家具组装图、象棋游戏(和大多数其他台式游戏)以及电路设计。与
IT 相关的 DSL 示例包括 HTML、SQL、WS-* 标准、业务流程执行语言(Business Process Execution
Language,BPEL)和 POV 场景描述语言。
与这些 IT 示例相关的 DSM 示例包括所见即所得 (WYSIWYG) HTML 编辑器、BPEL 编辑器和 POV Modeler。
定义 DSL 是非常有价值的,因为 DSL 通过设置非常特定的范围来帮助集中于特定的领域。一方面,小心设置的范围可以确保领域专家以结构化和详细的方式捕获知识和专门技术。另一方面,专门知识和技能可由该领域的用户提取并重用。
DSL 的另一个重要方面在于,它使您可以指定粒度,这意味着在详细描述和模糊描述之间寻求妥协,定义
DSL 部分将对此进行介绍。
为什么应该使用 DSL 而不是使用通用语言(general purposed language,GPL)呢?与 DSL 相比,GPL
使用足够简单和基本的词汇来描述任何领域,而不描述明确细节。可以使用 GPL 来实现相同级别的领域表示和理解,但是与 DSL 方法相比,GPL
对关于该领域和通用语言的预期知识级别要求是相当高的。DSL 的一个主要优点在于,它需要很少的时间即可理解和传达某个领域的详细信息。它需要很少的时间来学习使用相关工具。
例如,业务应用程序通常是使用复杂的软件解决方案来实现的,但是大多数解决方案都使用相同的构件(模式)来交付业务功能。DSL 使您可以对软件解决方案进行抽象,并隐藏实现细节。DSL
还可以使用来自业务领域的词汇,并为 IT 领域提供转换。
遗憾的是,存在使用得非常糟糕的 DSL 的实例(或反模式)。在这样的情况下,DSL 被用在错误的上下文中,并且通常是用于错误的目的。几个反模式的示例如下:
- 具有错误上下文的 DSL,并混合了抽象级别(例如,混合了用例和用户界面细节)
- 具有错误上下文的 DSL,并且未能分离关注事项(例如,混合了持久性细节和用户界面细节)
- 具有太多约束的 DSL,这是由僵化的结构所导致的(例如,复杂应用程序的配置细节)
- 具有太多元素(通常是由于未确定模式而导致的)或模型元素实例最终出现在元模型中的 DSL
- 具有冗余内容(例如,混合了用于不同类型的用户界面的用户交互流,包括 Web 浏览器,以及网页交互流)
领域 是一个良好定义的主题方面,并使用一组有限的概念进行描述。DSL 和 DSM 中的领域通常以元模型的形式捕获,如
图 1 所示。设置恰当的领域范围和正确地定义边界是关键成功因素(将在稍后讨论)。
可以使用不同的表示法、技术和工具以许多不同的方式定义 DLS 的领域。大多数情况下,为 DSL 指定的领域被描述为元模型。这是一种流行的方法,因为:
- 元模型是自描述性的,并使用 DSL 来捕获 DSL 的元模型(领域)。
- 元模型相对容易理解;它们与实体关系模型非常相似。
- 元模型易于使用和重用于进一步的处理(模型驱动的开发)。
- 元模型非常适应模型驱动的体系结构方法。
图 1. 元-实例象限中的概念
使用实体关系模型是一种定义 DSL 的形式。还存在其他方法和形式,但是本文将集中于实体关系建模技术,因为此项技术与稍后将描述的技术更密切相关。Eclipse
的 EMF 项目也正在遵循实体关系建模技术来捕获 DSL。实体关系模型相对易于捕获、易于维护、易于使用工具来支持,并且概念通常得到了很好的理解。
定义 DSL
成功的领域规范的秘诀是拥有描述该领域的良好元模型。(稍后将讨论良好元模型的要素。)捕获元模型并不是无足轻重的任务,而是需要大量的技能和经验。技能可以通过实践来获得。捕获元模型是某种类型的抽象,通常是架构师应该具备的技能。此活动所需要的实际技能是能够平面化层次(树形)结构。
存在各种捕获元模型的不同方法和技术。以下示例也许可以帮助您着手开始此任务。
- 使用纸和铅笔,开始绘制您希望获得的结果的模型实例。务必记住以下几个简单概念:
- 您是在绘制图而不是树(尽管树也是图)。
- 使用方框来表示元素。
- 在方框之间使用直接连接。
- 使用方框中的方框来表示包含。
- 此时不要过于担心外观,虽然大致了解以后将如何表示元素也是不错的。其他元素也是如此,例如连接。
- 开始考虑各个方框的属性。
- 不要考虑元素的可视化放置;例如,左侧的方框、位于 (10,10) 的方框 (x,y)。
- 考虑捕获和绘制多个实例。
- 考虑捕获同一个模型的不同表示形式(结构)。此方法可以帮助您更好了解领域,优化元模型,并使您可以开发工具友好的元模型。
- 一旦拥有了一组很好的模型实例,并且这组模型实例似乎表示了您希望捕获和传达的概念,即可开始使用建模工具(此处为 EMF)来捕获元模型并平面化元素层次结构。建模环境和工具的约束将指导您开发有效的元模型。
- 不存在用于测试元模型的简单方法,因此最好的选项是反复试验,直到该模型(基于已构建的元模型)与预想的结果密切匹配。幸运的是,创建工具是方便快捷的,因此试验过程也相对快速。
不要直接从该元模型的第一个实例构建关系图编辑器;应该首先使用更简单的模型编辑器,例如 EMF 树编辑器。
- 在树编辑器按预期工作以后,就可以开始构建第一个关系图编辑器了。这很可能也是一个迭代过程,同样应该使用反复试验的方法。
该元模型可能不是“工具友好”的,意味着该元模型的约束不允许您按最初计划的方式构建可视化编辑器。在此情况下,唯一的选项是返回到最初的元模型,并尝试使用不同的结构和构造来捕获相同的概念。设计工具友好的元模型是一项从经验中获得的技能。
在尝试捕获良好的元模型时考虑以下事项。
- 定义范围
- 确保模型中捕获的信息级别一致并且相关。仅捕获相关信息;不要构建或使用复杂的通用模型。在模型中捕获适当级别的详细信息,而不是混合不同的抽象级别。在捕获元模型时应用关注事项分离原则(将模型组件化)。确保模型中捕获的信息不会在开发过程中在其他模型中重复
DSM。在理想的情况下,所有的信息具有单个权威视图或模型,其他模型只是反映内容。
例如,基础设施建模将从集中于位置和可能功能的概念性节点的捕获开始,而不是考虑针对性能、可用性或类似特性的关注事项。下一步,您可以构建一个更特定的模型,其中包括前面放弃的关注事项(性能、可用性等等)。在非常详细的级别,该模型可以包括基础设施的物理细节,包括网络地址、计算机类型、规格等等。
- 粒度
- 不存在用于计算或决定正确粒度级别的神奇公式。可以提出以下问题以帮助您做出决定:
- 模型中应该捕获多少信息?
- 需要多少信息才足以充分理解该领域并且易于传达?
- 信息在什么情况下太多?
考虑粒度的一种方法是在模型中捕获细节和在转换中捕获细节之间寻找平衡:
- 捕获太多的细节就像是在使用某个模型或领域特定语言来开发代码。在此情况下,留给转换的细节所剩无几。
- 未在模型中捕获足够的信息会妨碍适当级别的理解和传达。在此情况下,大多数细节不得不包括在转换中。
- 确定领域
- 使用 DSL,提出应该确定多少个领域的问题是恰当的。答案取决于领域的上下文。与许多 IT 术语一样,领域
是一个被反复使用的术语。通常,在考虑要指定的领域数量时,您需要在两件事情之间进行区分。
首先,始终存在可正确地称为领域的更大领域。这始终适用于其中某些元素仅远程相关的更大上下文。Java™ 2
Platform, Enterprise Edition (J2EE) 应用程序就是一个示例。这个大型领域包括 Enterprise
JavaBeans (EJB)、Servlet 和 JavaServer Pages (JSP) 组件以及其他相关构件。
其次,DSL 中的领域上下文要比前一情况更小和更集中。在无法用特定的领域术语来表述的情况下,应该将这些领域称为子领域或微领域。J2EE
应用程序中的 EJB 模块就是一个示例。这个特定领域仅考虑各种类型的 EJB 和与之相关的构件。
- 处理语义
- 所有可能的元素安排(词汇)在领域中都具有特定的解释。不存在有关如何安排语言元素或如何解释这些元素的歧义性。需要在所定义的领域范围中表示的所有事物都可以使用该语言
(DSL) 来表示。
元模型中定义的约束是语义的关键驱动因素。约束可以确保无效的安排不会出现在模型中。
- 工具友好性
- 对于元模型,工具友好性是指为特定元模型 (DSL) 设计和开发工具的容易程度。“工具友好”不是科学度量;它是一种从工具开发的角度表示模型质量的方法。决定工具友好性是一项简单的测试:如果很容易为模型开发工具(在此例中为关系图编辑器),则模型是工具友好的。采用工具友好性是用于实现以下目的的很好做法:
- 更容易和更快的工具开发
- 快速的原型开发
- 加强的工具易用性
- 更好的领域理解
- 更好的模型构造和更高的模型重用机会
遗憾的是,在捕获元模型时,减轻工具开发人员的工作不属于优先考虑的事项。自底向上的方法通常产生工具不友好的元模型。然而,遵循自顶向下的方法(或任何其他方法)来捕获元模型并不能保证工具友好性。
领域特定建模
在诸如 IT 等工程科学中,专家使用模型、关系图和草图来描述问题或解决方案的特定细节。对可视化表示形式的需要起因于围绕该行业的高度复杂性。抽象和自动化论证了可视化建模需要的合理性。
IT 中的工程师处理各种输入、输出、工作产品和可交付件。一个输出可能成为另一个工作产品的输入。模型和关系图通常就是实际工作产品或其中的一部分。信息流、先前成果的重用以及工作流自动化论证了使用模型而不是使用简单关系图的合理性。
构建和使用工具方法应该实现:
- 架构师或程序员对领域的更好理解
- 工具友好的元模型
- 非常高的重用可能性
- 有关易用性和可用性的信息
- 更接近元模型的设计
- 所捕获的模型中可潜在地在其他场合共享和重用的语义
根据“一幅图胜过千言万语”的精神,使用为特定领域定义的元素的可视化模型表示形式可以完整地描述整个解决方案。尽管可以使用许多技术和技巧来为
DSM 提供工具支持,但是本文仅讨论一个选项:使用 EMF 和 GMF 的 DSM。
在深入到使用 EMF 和 GMF 的细节之前,让我们看一下 DSL/DSM 与统一建模语言(Unified Modeling
Language,UML)路线之间的简要比较。务必理解的是,存在不同的路线不是为了彼此竞争。
选择 DSL/DSM 还是 UML?
在某些方面,使用 DSL 和 UML 的建模处于该范围的两个对立端。UML 是一种统一(或通用)建模语言;它可以支持几乎任何模型。DSM
是一种领域特定 建模语言。它只能支持特定类型的模型。
使用 LEGO 玩具作为类比,将 UML 看作是一堆具有几种不同颜色和几种不同大小的基本标准积木块。DSL 就像是中世纪骑士城堡工具箱中的一组大尺寸的砌块、具有不同颜色和纹理的石块——与中世纪城堡的整段石墙类似的大型元素。可以想象人们如何通过该工具箱建造非常吸引人的实用城堡。但是,在基本石块基础上建造起来的城堡缺乏适当的颜色、纹理和中世纪特征。
存在两个单独的技能方面:定义 DSL 所需要的技能,以及使用该语言所需要的技能。
- 开发该语言 (DSL) 或建模工具 (DSM)
- 使用 EMF 和 GMF 需要 EMF 的知识,EMF 不过就是一个实体关系建模工具。GMF 本身就是一种 DSL,您必须理解它才能开发图形关系图编辑器。
使用 UML2 的开发需要充分了解 UML2 元素、元素之间的关系,以及如何定义构造型来对元素进行自定义。以图形关系图编辑器为例。如果该编辑器的功能不足够,则存在某种程度的自定义空间,此自定义需要特定的开发技能。
- 使用该语言 (DSL) 或建模工具 (DSM) 本身进行开发
- 对于 EMF 和 GMF,一旦了解了特定的领域,开发是非常简单的。
在 UML2 的情况下,开发人员必须熟悉特定的领域和 UML2 本身。
UML2 的用户群比 EMF 和 GMF 更大,但是 EMF/GMF 阵营正在不断发展(通过邮件列表上的活动和有关该主题的日益增加的文章数量可以判断出这一点)。相反,谈到开发
DSL/DSM,EMF 和 GMF 通常是首选的技术。选择 EMF 和 GMF 的主要原因是 UML 关系图中缺乏对某些更复杂的构造的支持。
在将 IBM® Rational® Software Architect 中的 UML2 与 RSA 中的 EMF
和 GMF 做比较时,团队开发是一个重要的方面。除了基于 Eclipse 工作台的标准团队开发支持以外,Rational Software
Architect 中的 UML2 工具还具有高级的建模功能以支持团队开发。这些功能包括模型比较、差异突出显示和模型合并。EMF
目前不具备相同级别的团队开发支持。
EMF 是来自 Eclipse 工作台的成熟技术。有关使用 EMF 的详细信息超出了本文的范围。有关高级功能的概述和信息,请参见
参考资料。
使用 GMF 进行图形建模
作为 Eclipse 中的一个相对较新的项目,GMF 提供了一个为 Eclipse 工作台开发图形工具和关系图编辑器的框架。该框架包括两个部分:
- GMF 运行时(Eclipse 的一部分,并提供用于图形工具的基本的公共元素和服务)
- GMF 工具(帮助进行使用 GMF 运行时的 Eclipse 插件的开发,以交付最终的建模工具)
GMF 本身的工具是一组专用于图形建模工具开发的 DSL。从本质上讲,GMF 合并各种图形建模工具中的功能、能力和模式(超集),从该工具超集中提取可变性,并最终为开发模式提供一个建模前端。
GMF 是用于为 DSL/DSM 开发工具的理想选择,因为它:
- 方便快捷
- 遵循模型驱动的方法,无需编写任何一行代码即可产生结果
- 提供了可满足图形建模工具环境的大多数复杂和苛刻要求的完善级别
- 产生高质量的工具
建模方法
图 2 显示了用于构建建模工具、建模本身和在模型基础上产生构件的最基本方法。
图 2. 基本建模方法
从本质上讲,如图所示,存在两个起点:
- 首先创建元模型,而不考虑最终构件的关注事项
- 使用最终构件来驱动元模型的开发或在最终构件基础上生成元模型
从元模型开始,开发人员必须建立该特定领域的元模型或语言。约束可以充实元模型,以确保模型实例的语义正确性和有效性。大多数图形编辑器都可以在元模型的基础上生成,但是其他部分则必须手动进行定义。可以为图形编辑器指定一组新的约束,因为图形表示形式可能使用与原始元模型不同的构造来进行建模。可以使用图形编辑器来创建和编辑模型实例。这些模型是模型驱动的开发的结果。模型成为转换的输入,以生成最终构件(例如代码)。
前面提到的两个入口点与两种基本的建模方法相关:自顶向下和自底向上。
自顶向下的建模方法首先捕获元模型,然后开发转换和代码生成器以产生构件。表 1 显示了自顶向下的建模方法的优点和缺点:
表 1. 自顶向下的建模方法的优点和缺点
优点 |
缺点 |
|
- 可能不会产生预期的构件或提供用于生成构件的理想输入。
- 由于前述原因,正反向工程可能中断。
|
自底向上的建模方法从构件开始,基于实例构建模型,最后在模型的基础上定义元模型。表 2 显示了自底向上的建模方法的优点和缺点。
表 2. 使用自底向上建模方法的优点和缺点
优点 |
缺点 |
- 代码(构件)生成器要么很容易开发,要么是其中一个副产品。
|
- 开发元模型来表示构件的概念和上下文是非常繁琐的。
- 创建工具友好的元模型非常繁琐,需要技能和专业知识。
|
上述两种方法的组合是“中间相遇”(meet in the middle) 方法,此方法利用了前述两种方法的优点。开发从两个方向开始,在概念元模型基础上创建工具,同时基于构件创建元模型。通过一组转换建立所获得的两个元模型之间的联系。表
3 显示了这种组合方法的优点和缺点。
表 3. 使用“中间相遇”方法的优点和缺点
优点 |
缺点 |
- 从现有的模型和构件开始;不需要开发新的模型和构件。
- 可能获得预期用于图形建模和用于生成构件的结果。
|
- 需要深入理解现有的元模型(自顶向下和自底向上),因为它们很可能来自于不同的来源。
- 很可能需要附加的开发或使用映射工具来进行转换。
|
实际上,自顶向下的方法很少产生元模型以支持开发构件的生成。这种方法对于捕获概念及其关系是非常出色的。类似地,自底向上的方法很少产生可有效地传达或描述特定领域的元模型。尽管可以遵循纯粹的自顶向下或自底向上的方法,但这样充满了挑战。
约束
约束和验证经常作为与元模型和 DSL 相关的主题一并进行讨论。约束 确保模型实例在语义上是正确的。验证
是检查模型实例上的约束的过程。验证还可以为建模人员提供反馈,从而帮助纠正模型。
用 DSL 术语来说,约束确保使用该语言的词汇来构造的句子是有意义的。可以通过不同的形式定义元模型的约束,包括使用:
- 某种约束语言,例如 OCL
- 特定扩展点的某种编程语言,例如 Java
- 正则表达式,例如 regexp
约束不仅限制模型中的某些构造,其中某些约束还可以计算和填充元素的值。还可以在元模型中捕获一些较简单的约束,而不需要用于支持复杂约束的扩展。这些约束可以是必需属性、基数或预定义(缺省)值。
转换
转换用于将表示源实例的数据和结构映射到表示目标实例的新结构和数据。转换中的源和目标可以是模型或任何其他构件。用 DSL 术语来说,转换是不同领域之间或某个领域和其他构件之间的映射操作。之所以需要转换,通常是因为实例(模型或构件)在不同的领域中、具有不同的格式或具有不同的版本。实际上,转换可用于各种目的,例如:
- 在模型基础上生成代码
- 将一个或多个模型映射到另一个模型(一对一或多对一)
- 在代码构件基础上生成模型
在使用转换时,具有相同元模型的模型实例之间的几个转换示例包括:
- 充实或扩展源模型
- 初始化源模型
- 更改源模型中的数据(包括版本更新)
GMF 应用程序的开发过程中有一组用作示例的很好转换。GMF 仪表板(Eclipse 视图)甚至提供了转换步骤、构件及其关系的可视化表示形式。
开发过程
为 DSL/DSM 开发工具是一个高度迭代的过程,如下所述。
- 开发元模型。可以通过各种格式捕获元模型,例如 XML 模式 (XSD)、带注释的 Java 代码、ECore 模型或 Rational
Rose® UML 模型。
- 生成基本工具将产生一个简单的树形编辑器。此编辑器已经是一个可用的工具,没有新奇的功能,仅用于满足基本的编辑需要。
- 使用该基本工具来测试模型。重复从步骤 1 开始的步骤,直到达到预期的结果。
- 通过以下方式创建并指定工具模型:
- 创建工具面板 (.gmftool)。
- 创建图形元素及其可视化表示形式 (.gmfgraph)。
- 创建领域模型、图形和可视化元素以及工具面板之间的映射 (.gmfmap)。
- 在前面步骤中指定的模型的基础上生成工具。
- 测试该图形建模工具。
从步骤 4 开始重复,直到达到预期的结果。
此时,基于某个元模型的图形建模工具已经可用了。如果该建模工具产生输出,此输出可能只是一个持久化的模型实例,则无需做其他工作。如果预期该模型将用作所生成的构件的基础,则很可能必须开发一组转换。
下面的图来自于 GMF Eclipse 项目中附带的 Mindmap 示例。这些图显示了一组用于开发 GMF 工具的典型模型和项目构件。图
3 显示了 Mindmap 工具。
图 3. 用于 Mindmap 工具的 .ecore 模型
图 4 显示了工具面板定义。
图 4. 工具面板定义
图 5 显示了图形元素和形状定义。
图 5. 图形元素和形状定义
图 6 显示了 .ecore 模型、工具面板以及图形节点和形状之间的映射定义。
图 6. .ecore 模型、工具面板以及图形节点和形状之间的映射定义
图 7 显示了项目细节和构件。
图 7. 项目细节和构件
图 8. 带有所有模型的 GMF Dashboard
Eclipse 是使用 EMF 和 GMF 来进行 DSL 和 DSM 开发的开发环境。IBM 的 Rational Software
Architect 包括了为 DSL 和 DSM 开发工具所必需的所有 Eclipse 项目。相关项目包括 EMF、GEF、GMF、UML2
和 EMFT。Eclipse
Modeling Project 具有这些项目的详细信息。前面描述的工具开发的结果是 Eclipse 插件。本质上,工具的运行时环境是
Eclipse 工作台。
主要开发用于建模的插件的两种使用形式如下:
- 安装在现有的 Eclipse 工作台之上,使其成为开发环境不可或缺的一部分。
- 安装为独立插件,仍然使用 Eclipse 工作台,但是独立于 Rich Client Platform 之上的其余开发工具而运行。
领域特定语言和领域特定建模是许多不同 IT 角色(甚至 IT 以外的角色)的工具箱中的强大工具。通过使用 DSL 和 DSM,IT
架构师可以清楚理解他们所处理的领域,并且能够更有效地传达该领域的细节。然而,务必记住 DSL 和 DSM 不是解决所有问题的万能答案——它们的适用性取决于所构建的语言和工具的优劣情况。
学习
获得产品和技术
讨论
|