阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

Java 应用开发中代码生成工具的作用

  • 2009-09-14
  • 本文字数:5267 字

    阅读完需:约 17 分钟

近来,随着各种代码生成工具的不断涌现(如 SpringSource 的 Spring Roo Skyway Builder Community Edition 6.3 及 Blu Age M2Spring 等),人们又将注意力转移到了这些代码生成工具在企业级 Java 应用开发中所起的作用。

模型驱动开发(MDD)正获得越来越多的关注,而在一个典型的 Java 应用中有些内容完全是可以自动生成的。典型的 Java Web 应用包含数据访问对象(DAO)类、XML to Java 映射文件、Spring、Log4J 配置文件等,这些内容其实都是能够自动生成的。

Roo 是个双向代码生成框架,可以生成 Spring Web 应用所需的大多数基础代码。Roo 提供了一个命令行 shell,同时具有 tab completion、上下文感知操作以及命令行提示等特性;它还会以标准的目录格式构建 Spring 应用,管理构建配置文件、辅助开发者创建领域对象并能为基于 REST 的 Web UI 自动生成 Web 层代码。

Skyway Builder Community Edition 6.3 于上个月发布,它提供了对 Spring MVC 的支持,可以根据新建或现有的领域模型生成基于 Spring 的 Java CRUD 应用。它集成了 Spring DSL,还能生成 Spring MVC 与 Spring Web Flow 应用代码。Skyway Builder 商业版 Skyway Builder Enterprise Edition (EE) 6.3 集成了 IBM Rational Software Architect 以将 UML 转换为 Spring 应用代码。此外,它还提供了对 DWR(JavaScript/JSON)的支持,可以通过 Spring services 开发 RIA 应用;还能够通过 JET 技术定制项目级的代码生成模板。

IBM 的 MDD 工具(叫做 Rational Rhapsody )支持 UML2 与 SysML、需求跟踪、应用代码生成以及针对测试进行设计(DFT)等特性。Rhapsody 是个双向的模型驱动解决方案,可以通过需求图、用例图、序列图、活动图以及状态图捕获项目需求。接下来用户就可以根据模型创建对需求的跟踪链接,这种链接能自动提供跟踪、影响分析以及覆盖文档等功能。Rhapsody 还支持模型驱动测试(MDT),所谓模型驱动测试,实际上是一种新的方法论,它将 MDD 的优点引入到了测试过程中。凭借 MDT,工程师可以不断对设计进行模拟以及早定位错误,同时还可以自动化单调乏味的测试、进行基于需求的测试以验证设计是否符合需求,它还能通过 IBM Rational Rhapsody Automatic Test Generation Add On 根据设计自动创建覆盖率测试。

最近 Blu Age 凭借其产品 M2Spring 也加入到了代码生成工具的阵营。M2Spring 联合使用了 MagicDraw UML 与 Blu Age Agile Model Transformation 进行建模及自动生成基于 Spring 架构的应用代码。它能够在服务层(业务规则、应用服务及 Web Service)、表示层(用户界面、用户角色及安全策略)和持久层(业务对象、DAO 实现及 DAO finder)上生成 Spring Web 应用所需的类和其他代码。M2Spring 支持多种模型与 JEE 技术,如 UML 2.2、OCL 2.0、XMI 2.1、EMF UML2 2.x XMI、 Struts 、Spring 及 Hibernate.

还有一些开发工具也支持代码生成,如 Project Lombok 和 Spoon。Lombok 具有如下一些特性:自动生成默认的 getter/setter 方法、自动化的资源管理(通过 @Cleanup 注解)及注解驱动的异常处理等。

InfoQ 采访了 Spring Roo 的项目经理 Ben Alex 以深入了解 Java 应用开发中代码生成工具所起的作用。Ben Alex 说到大多数的开发者每天都在使用代码生成,无论是通过 Eclipse 的“getters/setters”特性还是从别的地方拷贝过来一段代码,本质都是如此。其主要动机是尽快为特定的需求实现解决方案,避免每次都花费时间研究最佳的解决办法。现代的代码生成工具的动机也是如此,只不过将应用范围扩大了,从简单的“getters/setters”自动生成到提高应用生产力的层次上,比如构建多层的应用。就像是“getters/setters”自动生成一样,现代的代码生成工具也非常容易使用,其生成的代码与我们自己动手编写的差不多,同时我们还可以轻松修改生成的代码。

在使用代码生成工具之前,开发者需要注意哪些方面呢?

开发者可以像评估 IDE 工具那样来评估代码生成工具。要是我的话,我就会问这个软件会提升个人生产力么?学习和使用曲线如何?我所在的组织允许使用这个软件么?一旦使用之后,要是不想用了能行么?软件的维护力度如何?是否有相应的社区呢?软件的质量如何(未解决的缺陷、最终用户的博客以及架构性的资讯信息数量等等)?能否通过插件的方式轻松增加新的功能呢? 除了像使用 IDE 时可能会遇到的问题外,你还需要问自己特定于代码生成工具的问题:从长远来看,这个代码生成工具会持续不断地维护我的代码么(比如提供了哪些双向支持)?操作代码生成工具的方式对我的知识、技能与经验有哪些要求?与我经常使用的 IDE 的协作能力如何?能否与新版本的 IDE 协作良好,抑或是安装了新版本的代码生成工具或是 IDE 时会不会导致崩溃的情况发生?生成的代码是否自然、干净、一致且高效呢?其使用方式是否足够灵活以便让我能按照自然的方式工作?其是否完全是自动化的,还是需要我做一些额外的工作?新版本的代码生成工具(或是插件)不会搞乱我的项目吧?

在大多数应用中,开发者都需要手工编写业务逻辑与验证规则代码,而这些代码都不太容易自动生成,那代码生成工具是如何解决这个问题的呢?

Hunt 与 Thomas 在 The Pragmatic Programmers 一书中提到了两类代码生成方式:被动的与主动的。 所谓被动生成方式就是只运行一次代码生成工具来生成结果,然后手工维护生成的代码。很多开发者都在 IDE 的帮助下使用过被动生成方式,如“getters/setters”生成器。被动生成方式的输出结果都是由开发者决定的:他们可以通过命令来生成想要的东西。被动生成方式的缺憾在于开发者必须要手工维护生成的代码,因为生成工具不会再对生成好的代码进行更新了。在你修改了生成代码所依赖的某些内容后这个问题就会变得尤为明显,因为此时生成的代码将会出错,而用户通常都会删掉代码并重新运行生成工具。

所谓主动生成方式就是每次运行时都会产生相应的结果,它需要一种方式来存储控制信息,这样就能运行并生成所需的结果。控制信息技术的差别非常大,但通常都是自动获取的元数据(比如来自于源代码解析与绑定)与通过 Java 注解、JavaDoc 标记、XML 文件、特殊的 GUI 配置等信息构成的用户首选项的组合。有了这些高质量的主动生成工具(比如 Roo),开发者可以像往常一样在标准的源文件中编写自己的逻辑,同时生成工具会检测到源文件的改变并只自动更新受影响的这些文件。因此我们无需告诉系统(比如 Roo)想要编写客户化代码了,因为这一切已经成为系统的一部分了。

如何将优秀的架构与设计实践应用到既有自动化的代码生成又有手工编写代码的应用开发过程中呢?

很多现代的自动生成工具都用来生成最初的应用骨架。这意味着所生成的应用反映了嵌入在生成工具中的最佳实践。接下来,通过正常的对生成器的操作又会不断鼓励用户使用这些最佳实践,因为后面生成工具所生成的代码也反映出了同样的架构模式。这种一致性对于那些团队成员水平参差不齐或是项目需要长期维护的组织来说是个巨大的优势。 自然,用户肯定要问的一个问题就是嵌入在生成工具中的那些最佳实践真的是最佳的么?对于该问题的答案就是:被众多用户与项目所用的生成工具通常都是最佳的,因为大量的设计反馈都会被集成到工具中。用户还可能会审视实际的架构、仔细审阅其可测试性、可维护性、设计完整性、可复制性、避免独占等等。此外,大多数高质量的代码生成工具都会让一些知名的组织来对其生成的架构进行认证(比如 SpringSource 就将 Roo 架构作为最佳实践)。

相对于传统的代码生成框架,其他手段比如 Grails(大多数代码都是在执行期生成的)效果如何呢?

Grails、Rails 及 Django 等框架提供了一种被动的代码生成方式,它们会生成初始的应用骨架和特定的代码如 Web 控制器。接下来会在运行期(通过动态语言或反射技术)执行主动代码生成工具在开发期所执行的动作。 静态语言编译期技术相对于动态语言运行期技术相比具有很多优点,同时一些缺点也是显而易见的。它们是两种完全不同的开发方法,没有谁比谁强的说法,也没有哪一种方法能适合于所有的项目。SpringSource 拥有 Roo 和 Grails,因此用户可以选择感兴趣的进行开发,无论选择哪一个都能享受到生产力提高所带来的乐趣,同时也都能利用 Spring 的巨大优势。

您是如何看待常规的模型驱动软件开发(MDSD)与特定的代码生成技术呢?

我深信寻求更高层次编程抽象的目标将会继续下去,然而当前的趋势(根据不断涌现的新框架的数量及采取这些框架的开发者数量得到的结论)则聚焦在编程语言的革新与 DSL 上。这些生成工具之间的一个主要区别在于其 DSL 方式,一些工具以简单的命令为特色(像是“create-controller”)而另一些则提供了高级的 shell(如 tab completion、上下文感知、命令隐藏等)。这些高级的 shell 不仅降低了使用难度,而且还简化了日渐强大的(以及更高的抽象层上)命令的使用。 综上所述,代码生成工具依旧会在软件开发中扮演着重要角色。静态语言仍将占据着统治地位(来源:Tiobe),同时这些语言还是需要借助于代码生成技术来提升程序员的生产力。甚至是动态语言框架也会在某些地方使用代码生成技术,如初始化应用结构、关键的应用代码等等。像更高层的 DSL、高级的 shell、创新性的编译单元分离及高质量的双向支持等未来趋势会一直支撑着下一阶段的代码生成技术革命。

InfoQ 还采访了 Skyway 团队的 Jack Kennedy 以了解软件开发中的代码生成技术。现在很多项目都使用了敏捷与精益软件开发方法学,如 Scrum XP 或是 Kanban ,那对于这类项目,代码生成技术会起到什么作用呢?就这个问题,Jack 回答到:

不管采用何种开发方法,基于模式的代码生成与自动化技术始终都会影响到软件开发生命周期的各个阶段(分析 / 设计 / 构建 / 测试 / 部署)。代码生成由需求中的概念性元素开始,然后将其转换为具体的基于模式的设计,最后又将设计转换为基于模式的代码与测试单元。对于敏捷与精益软件开发方法来说,使用基于模式的代码生成与自动化技术的动因是相当重要的。尽管这些开发方法对于小项目来说还是非常成功的,但在整个软件产业当中要想更加充分地采用这些开发方法还是面临着相当大的挑战,首当其冲的便是处理更大、分布式、复杂需求的能力。问题的中心在于对高素质开发人员的渴求以及缺少对大项目投入产出估算的能力。将基于模式的代码生成与自动化技术引入到软件开发的整个生命周期当中可以为组织提供如下好处:提升新手的能力并通过久经考验的组件来降低估算工作量。由于现代方法学一直强调持续集成与可论证的开发迭代,因此通过最小的投资和一致的质量来生成功能应用已经成为迫在眉睫的任务了。

代码生成骨架既可以节省时间、降低人力需求,又能保证代码质量,因为大多数应用代码(对于 Web 来说,就是 Log4J 与 Spring 配置文件等内容)都是自动生成的。这是代码生成工具的最大价值所在么?

基本上来说,软件生成平台通过自动化开发任务且遵循着目标部署环境的实现需求而为用户创造价值。其背后的隐式价值所在就是一致性、高质量及重用性。这种价值可以通过系统输入的代价与输出的成果之间的对比来进行衡量。总的来说,目标就是将代价最小化的同时保证价值的最大化。过去,代码生成工具仅仅被限制为根据生成系统所接收的“概念”而产生相应的代码。对于数据建模来说,这通常意味着可以使用一种格式来创建数据模型,然后生成该数据模型的“类”实现。很多 UML 解决方案都提供了这类生成工具(而且是专有排外的)。然而,在这种情况下,很多团队都发现投入产出比并不太好。 由于企业应用的实现技术已经简化了很多,同时软件的生成技术也已经很成熟了,与之对应,能够自动生成的功能范围得到了极大的扩展。具备生成基于 CRUD 应用能力的代码生成工具让很多开发者转向了现代的 RAD 开发环境与工具,这些工具包含了 DSL 与生成技术。这是生成技术的一个转折点,然而却还不能代表最终的价值所在。随着工业界不断提供更广泛的生成选项与输入格式,我们将会看到有越来越多的开发者转向代码生成技术。

你如何看待模型驱动开发与代码生成技术的未来?

未来一段时间的重点将放在填平传统的 MDD 方法 / 工具与新涌现的 DSL 之间的沟壑上,使快速应用开发成为可能。当前所用的 DSL 将会变得更加强大,当然复杂性也会不断攀升,它会整合安全、验证及应用流。生成技术将会跨越简单的“代码生成”阶段,转而成为构建与部署过程中的一个标准组成部分。可以从 UML 和 DSL 上获取的软件资产类型还将不断增加,同时还会跨越更广的技术栈集合以生成更多的应用代码。 随着开发者不断看到可以从这些简单的语法当中自动生成大量的功能,DSL 还将继续繁荣下去。这些 DSL 的工具选项将变得更加复杂,同时还将提供多种不同的输入方式与格式,包括文本与可视化元素。我们期望最后这些软件供应商会在生成并运行基于 DSL 的应用部署上展开激烈的竞争。

本文主要向各位读者介绍了代码生成工具在我们日常开发中所起的作用,不知各位在日常开发中是否使用过代码生成技术,请抽出一点时间参加 InfoQ 的小调查,谢谢!

查看英文原文: Role of Code Generation in Java Application Development

2009-09-14 01:555121
用户头像

发布了 88 篇内容, 共 258.4 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

浅谈 RDMA 与无损网络

青云技术社区

云计算 云原生 存储

【云小课】如何初步定位GaussDB(for openGauss)慢SQL

华为云数据库小助手

GaussDB GaussDB(for openGauss) 华为云数据库

极光笔记丨关于数据大屏一比一还原设计稿这件事

极光JIGUANG

大前端 数据可视化

第一本 Compose 图书上市,联想大咖教你学会 Android 全新 UI 编程

图灵教育

Compose AndroidUI

我所理解的社群—社群本质

sec01张云龙

社群 11月日更 社群运营

首次!统一调度系统规模化落地,全面支撑阿里巴巴双 11 全业务

阿里巴巴中间件

阿里云 云原生 中间件 双十一 统一调度

拥抱智能,AI 视频编码技术的新探索

阿里云视频云

阿里云 视频编码 机器视觉 视频编解码 视频云

经验分享|参与内部开源的心路历程

云智慧AIOps社区

大前端 数据可视化 知识分享 开源治理 flyfish

不要再重复造轮子了,Hutool这款开源工具类库贼好使

沉默王二

Java

手把手教你学Dapr - 1. .Net开发者的大时代

MASA技术团队

C# .net 微软 后端 dapr

模块三作业——外包学生管理系统架构设计

覃飞

如何穿透ToB客户生命周期的全链增长?

ToB行业头条

开源数据库风起云涌,openGauss 恰逢其时

openGauss

#数据库

企业如何选择合适的低代码平台?这6点不得不考虑!

J2PaaS低代码平台

低代码 低代码开发 低代码平台 企业数字化

项目管理常见问题系列(1)—资源不足

一叶而不知秋

项目管理

Nebula Graph 源码解读系列 | Vol.04 基于 RBO 的 Optimizer 实现

NebulaGraph

图数据库 源码解读

Nginx中间件渗透总结

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 漏洞挖掘

从 Linux源码 看 Socket(TCP)的accept

赖猫

c++ Linux 后端 服务器 epoll

Python代码阅读(第58篇):压缩列表

Felix

Python 编程 列表 阅读代码 Python初学者

手把手教你学Dapr - 2. 必须知道的概念

MASA技术团队

C# .net 微软 后端 dapr

前端的状态管理与时间旅行:San实践篇

百度开发者中心

大前端 san san-store 技术实践

openGauss支持国密SM3和SM4算法

openGauss

#数据库

一招教你通过焱融 SaaS 数据服务平台+ELK 让日志帮你做决策

焱融科技

云计算 分布式 SaaS 公有云 文件存储

我是一个程序员,总想引导亲朋好友走上编程的伟大航路......

图灵教育

程序员 App Inventor

盲盒app开发

CSS布局之display:flex(二)

Augus

CSS 11月日更

速来!开源中国首届飞算SoFlu组件开发悬赏赛来袭

SoFlu软件机器人

Java

Web 用户体验设计提升实践

Shopee技术团队

大前端 web开发 用户体验 交互设计 可访问性

月薪3万的大厂测试工程师裸辞3个月,送外卖谋生背后的真实感悟

六十七点五

程序员 程序人生 软件测试 软件自动化测试 测试工程师

就是简单,全球100多万读者,一起跑通前端HTML5与CSS3知识!

图灵教育

大前端 HTML5, CSS3

LevelDB Java&Go实践

FunTester

Java 自学 Go 语言 leveldb FunTester

Java应用开发中代码生成工具的作用_Java_Srini Penchikala_InfoQ精选文章