编辑推荐: |
本文主要介绍如何基于EA创建项目特定的代码生成器,接下来请阅读文章了解详情。
本文来自于Sparx 社区网站,由火龙果软件Alice翻译、推荐。 |
|
您是否曾经希望从EA UML或SysML模型生成代码?您是否尝试过EA的自定义代码模板框架?不要放弃特定于项目的代码生成器的梦想,下面来了解下它们是如何轻松的就可以实现的。
需要代码生成器
一个好的软件或系统架构相对于实现来说是一个更高的抽象层。 它应该是一个一致的模型,记录决策并忽略不必要的(通常是技术性的)细节。
例如,如图 1 所示的类图。它显示了一个域模型,该模型定义了商店允许客户订购商品所需的数据结构。对每个类的属性都进行了详细的建模,但省略了其他不必要的方面,例如访问属性的操作。
图1:UML模型示例
如果在开始实施之前先对软件架构/设计做了准备工作,那么代码生成可以避免很多繁琐且容易出错的工作。商业开箱即用的代码生成器通常不会更改抽象的程度。这就是为什么它们通常不符合项目需求的原因。
EA的代码模板框架可以根据项目的具体需求进行定制。但这需要一些初步的培训。通常,如基于Eclipse的EA
模型的代码生成中所述,很难达到预期的结果。
一个简单的项目专用代码生成器
我更喜欢使用 Java 或 Xtend 等通用编程语言来实现代码生成器。
特别是 Xtend 非常适合定制模板,因为它是模板的表达式。它们允许将可执行代码嵌入要生成的文本中。感觉就像在编程
PHP、JSP 或 JSX。 清单 1 中的代码显示了一个用 Xtend 编写的代码生成模板。 它为图
1 的类图中声明的类,生成 Java 类。
清单 1:用 Xtend编写的代码生成模板示例
清单 2、3 和 4 中显示的生成的 Java 代码看起来不像手写的,因为使用了限定名称而不是导入。
这将在后面的图 4 中通过方法 collectImports 和 printImports 得到改进。
清单 2:由清单 1 中的代码生成模板生成的类AbstractIDObject的 Java 代码
基于清单1中的代码模板生成的AbstractIDObject.java文件
清单 3:清单 1 中的代码生成模板生成的 OrderItem 类的 Java 代码
清单 4:清单 1 中的代码生成模板生成的类 Order 的 Java 代码
如果仔细查看清单1中的模板,您将发现它对EA一无所知。取而代之的是,它处理UML元模型的实例,这要归功于Eclipse
UML 2项目,它在Eclipse中可用。YAKINDU EA-Bridge是EA和UML之间缺少的连接。它是一个API,可提供对EA
UML和SysML模型的符合UML的读写权限。EA项目背后的数据库会自动转换为UML元模型的实例。作为开发人员,这具有三大优势:
1. 您的代码与其他基于 UML 2 项目的工具(例如 Papyrus)兼容。
2. 对 EA模型的高性能读写访问,无需对 EA的数据库模式进行逆向工程。
3. 您无需了解有关 YAKINDU EA-Bridge 的 API 的任何信息。作为开发人员,它对您来说是完全隐藏的,因为
YAKINDU EA-Bridge 将自身集成到 Eclipse 建模框架 (EMF) 的生态系统中。
YAKINDU EA-Bridge 带有一个可选的 Eclipse
IDE 集成,它允许实现特定于项目的代码生成器。这些代码生成器通常是原型开发的,并且仅在特定上下文中执行。因此,至关重要的是,与手动编码相比,减少开发工作量。要实现特定于项目的代码生成器,您所要做的就是将
EAP 文件放置在 Eclipse 项目中,并使用 @EACodegen 注释代码生成模板中的方法。带注释的方法应接受应为其生成代码的
UML 元素作为唯一参数并返回生成的文本。如果您的 EA模型由远程数据库(例如Microsoft SQL
Server)托管,则可以使用快捷方式文件 而不是EAP文件。
例如,通过主菜单项“ Project,Clean ...”自动或手动构建项目时,将为所有EAP文件中声明的所有UML类启动模板。当然,仅考虑模板项目中存储的EAP文件。生成的代码保存在类的限定名称指定的文件中。文件扩展名由@EACodegen注释的参数指定。Eclipse项目的结构如图2所示。
图 2:Eclipse 中的示例项目结构
请注意 YAKINDU EA-Bridge 是一个 API。 它允许您以任何方式处理
EA模型。 事实上,最初的用例是全面的代码生成器,例如基于UML架构的Autosar RTE生成器。
每个模型元素生成多个工件
让我们通过使用两种不同的持久性方法来实现一个产品线,使示例更加令人兴奋:一种使用JPA将数据存储在关系数据库中,另一种使用HBase作为大数据存储。
我建议实现一个可用于加载和保存实例的持久性管理器。只有基于JPA的产品才允许启动和完成交易。此外,我想将JPA特定的注释放在Java类中。图3显示了持久性管理器提供的方法。
图3:处理图1中的域类的PersistenceManager类的概述
现在的结果是,两个产品中所有六个类的实现都略有不同。在Java代码清单5,
6, 7 和 8示出了代码的摘录来实现。
清单5:HBase作为持久性方法的类文章的Java代码
清单6:使用JPA作为持久性方法的Article类的Java代码
清单 7:PersistenceManager类的Java代码的一部分,其中使用HBase作为持久性方法
清单 8:PersistenceManager类的Java代码的摘录,其中JPA作为持久性方法
实现产品线的可行解决方案是:
使用继承。这将需要为每个类定义一个带有公共
API 的接口,并为 JPA 和 HBase 实现它。结果是必须将应用程序的其余部分调整为仅在接口上运行,而不能在具体类上运行。
复制、粘贴和修改这两种产品的实现将避免修改应用程序的其余部分。保持两个变体听起来可能是合理的。但是,随着变体数量的增加,情况仍然如此吗?您应该仔细考虑复制和粘贴的利弊。
使用代码生成器生成产品特定的代码。实现代码生成模板的类可以基于一个通用的实现,每个子类可以调整产品特定的部分。
我更喜欢最后一种解决方案。图4中的概述显示了清单1的重构的类模板。每个引入的方法都会生成Java类的特定成员。这使我可以在产品特定的模板中覆盖这些方法。例如,在清单9中,可以看到JPA特定的注释位于类定义之前。
图 4:重构类 ClassTemplate
的概述
清单 9:用 Xtend 编写的 JPA 代码生成模板的摘录
path(Class, IFile)带有注释的模板子类中的方法@EACodegenFile用于定义应保存生成的代码的目标位置。
它有两个参数。 第一个是应为其生成代码的 UML 元素。 第二个是应该存储生成的代码的默认位置。 带注释的方法的返回值是调整后的生成代码应该存储的位置。
图 5 中的屏幕截图显示了所有模板。 箭头指向它们各自生成的文件。除了生产代码外,还会生成测试代码。
图 5:JPA 和 HBase 的代码生成模板以及生成的源文件
结论
现代通用编程语言(例如Xtend)非常适合实现复杂的代码生成器。输入可能是UML模型,可能是在Enterprise
Architect中建模的。YAKINDU EA-Bridge可以将Enterprise Architect模型背后的关系数据库即时转换为UML元模型的实例,并且将其完全隐藏。无需学习Enterprise
Architect提供的专有代码生成语言或对Enterprise Architect的数据库架构进行反向工程。
YAKINDU EA-Bridge 的 Eclipse IDE 集成允许人们在短时间内以低成本实现特定于项目的代码生成器。
这样可以省去很多繁琐、容易出错、盲目的实施工作。
如果您想亲自查看并运行完整示例,请尝试使用 YAKINDU EA-Bridge。
所提供的示例是 YAKINDU EA-Bridge 附带的示例之一。
火龙果软件提供团队协同建模环境的咨询服务,可以帮助用户搭建完整的团队建模和MBSE解决方案,详细信息请见
http://tool.uml.com.cn/ToolsEA/service.asp
希望本文对您的建模工作有帮助。更多的有关EA建模资料如下:
视频:http://tool.uml.com.cn/ToolsEA/jswd-ysm.asp?partname=sp
文章:
http://tool.uml.com.cn/ToolsEA/docea.asp?partname=wk
如果您希望了解更多信息:
本文使用的建模工具为EA,可以下载试用版http://tool.uml.com.cn/ToolsEA/download.asp
后记
希望您读了此文后有所受益。
如果您有经验乐于分享,欢迎投稿给我们。
如果您对我们的培训、咨询和工具感兴趣:
|