paluch.biz - Lombok的数据类是有害的!为什么我不再使用Lombok?


其实数据类就是数据结构,就是DTO,其和真正类是有本质区别,见鲍勃大叔实锤:类与数据结构的比较,使用数据类其实是一种倒退!这篇博客文章解释了从项目中删除Project Lombok背后的动机,它反映了作者个人的观点,并没有阻止特定的技术。

大约三年前,我开始了解Project Lombok,一个用来编写Java代码的库。我从一开始就喜欢它,因为它提供了很多有用的功能。我在实体(数据类)和值对象上工作很多,所以@DataKotlins data class非常方便并不令人惊讶。从字面上看,你可以获得更多的收益。我在这里提到Kotlin,因为它分享了我们从Lombok获得的一些属性。

在代码库中采用这种(语言代码生成)特征通常开始很慢。代码发展越多,组件使用这些功能的次数就越多,因为使用免费获得的功能很方便,而且您已经习惯了。Lombok注解或单个关键字为我们提供了属性访问器:equals/ hashCode,toString,产生的构造函数等等。

实际上,没有免费午餐这样的东西

原因如下:

意外复杂性
通过引入代码生成(这是Lombok和Kotlin data classes所做的),我们获得了很多功能,但真正的问题应该是:它是否是我想要的功能?或者我们是否希望明确控制功能?

在某些情况下,我们使用数据类是为了方便,我们发现我们隐含地使用了许多我们免费获得的功能,例如相等的检查。删除Lombok生成的代码后,许多测试开始失败,因为这些功能不再可用。缺少的功能引发了一个问题:是否需要此功能?(影响测试)

相反,采用明确的方法(不使用Lombok注解),可能我们的测试看起来会有所不同,或者我们会更清楚地了解具体功能。

在没有生成实用程序的情况下显式明确控制代码会强制您考虑功能是否真正需要。

什么是样板Boilerplate?
样板Boilerplate代码是我们重复需要编写,以实现某个功能而不是告诉代码我们希望此功能开箱即用的代码。典型的例子是属性访问器(Getters,Setters)和相等性检查(equals/ hashCode)。有时也是建设者builder模式。与我们之前的观点相反,将Lombok注释自己的组件并不是样板Boilerplate。它不精确,方便,不负责任。

围绕编译器工作
Lombok针对特定的编译器,现实世界是:Java发布节奏速度从Java 9开始提高,Lombok项目不是由公司驱动,而是由开源贡献者团队推动,时间有限。

Lombok阻止我们升级到更新的Java版本的组件:编译器内部组件发生了变化,Lombok还没有机会赶上。随着Lombok的使用遍布整个代码库,唯一的选择就是不升级。

但是:从长远来看,不升级不是一种选择。最终,Lombok迎头赶上,开辟了再次升级到新版本的道路。

插件
需要启用Eclipse或IntelliJ插件,如果没有正确的IDE设置,任何想要处理Lombok代码的人都会收到错误/警告提出问题:这甚至是如何工作的?

认知负荷
每个非显而易见的行为都会导致需要理解的复杂性。此外,每个非默认行为都会导致相同的路径。人们第一次使用这样的代码库需要了解代码库。虽然这不是特定于Lombok,但是为​​代码提供附加功能的所有辅助实用程序(代码生成器,AOP,JVM代理,一般的字节码操作)都有可能被描述为魔术。为什么魔术?因为在第一时间发生的事情并不明显。一旦有人向你解释这个伎俩,它就会变得明显。

别人改变你的(编译)代码
使用代码生成功能,我们就只能依靠其他人来做正确的工作。

意外复杂性2:构建​​​​​​​
我们发布了一个带有公共API表面的库,它带有一个源jar和Javadoc。默认情况下,Lombok .class仅适用于您的文件。这会导致源jar不包含生成的方法,Javadoc也不会列出生成的成员。为了获得正确的源jar和Javadoc,我们需要在构建中添加插件,首先对代码进行delombok(去Lombok),并允许源jar / Javadoc在delomboked源代码之上运行。

复杂性的增加通常伴随着更长的构建时间,我们可能会问自己,这是否值得我们得到。

双重痛苦​​​​​​​
不使用代码生成功能使代码显式化。显式代码总是揭示它的作用。显式代码需要设计。

打个比喻:你有一所房子,你把它租给一些房客,因为租房子里的利润是有利可图的。最终你弄明白你的房客很乱,你开始驱赶你的房客。一旦你的房客离开,你就会意识到这个烂摊子的范围,你开始清理房间。