数据类被认为有害

这篇博客文章解释了从我参与的项目之一中删除Lombok项目的动机。 它反映了我的个人观点,并不妨碍特定的技术。

大约三年前,我认识了Project Lombok ,这是一个添加Java代码的库。 我从一开始就喜欢它,因为它贡献了很多有用的功能。 我经常处理实体(数据类)和值对象,因此@Data或Kotlins data class非常方便也就不足为奇了。 从字面上看,您会得到更多的回报。
我在这里提到Kotlin是因为它共享了我们从Lombok获得的一些属性。

在代码库中采用这样的(语言生成)功能通常会开始缓慢。 代码发展得越多,使用这些功能的组件就越多,因为使用免费获得的功能*方便并且已经习惯了。 使用单个注释或单个关键字,我们选择了可以为我们提供属性访问器的对象,包括equals / hashCodetoString ,生成的构造函数等。

* :实际上, 没有免费的午餐之类的东西 。

现在,有人可以说,只使用您需要的东西,而您完全正确。 如果只需要属性访问器,请使用@Getters@Setters 。 如果希望获得equals / hashCode ,则添加适当的注释。 真正。 在许多情况下,我们认为我们需要更多的功能,因此为什么当使用单个@Data注释获得我们想要的(以及更多)时,为什么要将具有多个注释的代码弄乱了。 这不是样板吗? 因此,减少注释的数量似乎是一件好事。

好:不。

原因如下:

偶然的复杂性

通过引入代码生成(这就是Lombok和Kotlin data classes所做的事情),我们获得了很多功能,但是真正的问题应该是:我是否希望使用该功能? 还是我们想对功能进行明确的控制?
在某些情况下,出于方便考虑,我们使用了数据类。 随着Lombok的删除,我们发现我们隐式使用了免费获得的许多功能* ,例如相等性检查。 随着生成代码的删除,许多测试开始失败,因为这些功能不再可用。 缺少的功能提出了一个问题:是否需要此功能?

只需选择数据类,就可以很容易地忽略这个问题。 与此相反,采用一种明确的方法,我们将花费更多的时间讨论该主题。 可能我们的测试看起来有所不同,或者我们会更明确地了解特定功能。

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

什么是样板?

样板代码是我们反复需要编写以公开某些功能的代码,而不是告诉代码我们希望此功能开箱即用。 典型的示例是属性访问器(Getters,Setters)和相等性检查( equals / hashCode )。 有时也有构造函数。
与我们以前的想法相反,将Lombok注释分解为自己的组件并不是样板。 它不精确,方便且不负责任。

在编译器周围工作

这是Lombok特定的方面。 Java编译器从未打算用于Lombok要做的事情。 Lombok的维护者为实现Lombok所做的事情做了出色的工作。 这是以针对特定编译器的编译器中的几种解决方法为代价的。 javac所需的内容在某种程度上与Eclipse的ecj需要执行的操作不同。

在静态布局中,JDK和Eclipse IDE永不改变,一切都很好。 但是,现实世界是不同的。 Eclipse发布了更新程序,从Java 9开始,Java发布节奏加快了。Lombok项目不是由公司驱动的,而是由时间有限的开源贡献者团队驱动的。

过去,Java升级导致Lombok成为阻止我们升级到较新Java版本的组件:编译器内部发生了变化,Lombok尚无赶超的机会。 随着Lombok用法遍及整个代码库,唯一的选择就是不升级。

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

插入所有东西!

Lombok的一个方面是它需要告诉您的IDE有关生成的类成员的信息。 尽管您的代码中没有例如Setter,但在编译后的代码中却有,所以您的IDE需要知道这一点,以免出现错误。 对于IntelliJ和Netbeans,这不是什么大问题,因为您可以启用注释处理并使用可选的IntelliJ插件。 对于Eclipse,您需要一个可修改Eclipse行为的代理。 如果没有正确的IDE设置,那么任何想要处理代码的人都会收到错误/警告,并提出以下问题:那怎么办?

认知负荷

从某种意义上说,每种非显而易见的行为都会导致复杂性。 同样,每个非默认行为都导致相同的路径。 初次使用这种代码库的人们需要了解如何掌握该代码库。 尽管这不是Lombok特有的,但所有为代码提供附加功能的辅助实用程序(代码生成器,AOP,JVM代理,一般来说字节码操作)都具有被描述为魔术的潜力。 为什么是魔术? 因为在第一刻发生的情况并不明显。 一旦有人向您解释了这个窍门,它就会变得很明显。

其他人更改您的(已编译)代码

使用代码生成功能,我们可以依靠其他人来完成正确的工作。 我们会购买它们,因此他们的工具为我们提供了对我们有用的功能。 我们不再需要为equals / hashCode正确的实现而烦恼,添加属性变得不费吹灰之力,因为这一代人为我们代劳。 手动扩展equals / hashCode并非易事。 某些工具可以为我们做到这一点,但是,正如您可能已经预料到的,我们在不大幅改善我们状况的情况下将tool2 tool1 tool2
有时,工具会更改其生成代码的方式或生成的位以及停止生成的位。 找出这些变化并不是一件有趣的事情,但是如果我们已经购买了他们的编程模型,那么我们就别无选择。 唯一的选择是退后,这是以手动实施为代价的。

偶然的复杂性2:构建

根据上下文,这可能仅与我们的项目有关。 我们附带了带有公共API表面的库,并附带了源jar和Javadoc。 默认情况下,Lombok仅适用于您的.class文件。 这将导致源jar不包含生成的方法,并且Javadoc也不列出生成的成员。 从消除样板代码开始,随着构建复杂性的提高而继续。 为了获得正确的源jar和Javadoc,我们需要向该插件中添加插件,该插件首先要对代码进行delombok,并允许源jar / Javadoc在delomboked源之上运行。

根据您的设置,使用delomboked的源仅用于源jar和Javadoc。 这意味着您将一个版本的代码用于文档目的。 该代码与您用于编译的代码不同。 Lombok本质上导致相同的输出代码。 使这一方面变得明显会使我们感到难受。

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

Lombok正在分化社区

即使前面的部分听起来好像我们正在处理严重的问题,但其中许多可能是特定于我们的项目上下文的。 Lombok承诺减少样板代码。 它做得很好。 在面向数据的环境中工作,在该环境中我们需要用于测试的各种对象群甚至在生产代码中,都需要大量的代码才能使用适当的数据对象/值对象。
hashCode提供良好的实现并hashCode 。 由于不正确的hashCode实现,有两个CVE。 忘记在equals / hashCode添加字段是错误的另一个常见来源。
使用代码生成时,我们消除了这些bug来源。 此外,不存在的代码也不会影响我们的测试覆盖率统计信息。 这并不意味着它不需要测试。

查看Lombok删除提交的统计信息,我们看到:

删除:300行
新增:1200线

这很好地说明了使用Lombok带来的好处。 一旦在一个地方使用了Lombok,我们通常会在其他地方继续使用它-因为它已经在类路径中了。 查看已删除的300行,我们应该改为将它们删除为150行,因为它通常是一个import语句和一个注释,使我们在便捷代码和手动维护代码之间的比例大致为1:8。

我们不需要支付任何代码行,但是拥有更多代码会带来更大的维护面。

看看我的推文 ,有非常相反的意见。 这些反应就是为什么在您应该/不应该使用Project Lombok或Kotlin数据类时没有唯一答案的原因,因为它始终取决于您的团队,上下文和所编写的代码类型。

双重痛苦

不使用代码生成功能会使代码明确。 显式代码始终可以揭示其作用。 显式代码需要设计。 由于立即得到的结果和最初的简单性,进入代码生成功能很诱人。 一旦使用了这些功能,我们将经历不同的情况,并了解尚不明显的方面。 由于相关的成本,很难消除一个非常有益的功能。 还记得1:8的LoC比率吗?

仅仅因为我们想摆脱代码生成,并不意味着我们可以免费删除该工具收到的功能* 。 而是意味着我们需要自行提供此功能。

我这样说:您有一所房子,您将其出租给某些租户,因为租用房屋可以赚钱。 最终,您发现租户很乱,并且开始摆脱租户。 租户出门后,您便会意识到混乱的程度,并开始清理房屋,以免房屋松动。

最终结果是相同的:您为该学习付出了很多努力(可能还有金钱)。

如果您的租户行为正常,则没有理由改变现状。

翻译自: https://www.javacodegeeks.com/2019/07/data-classes-considered-harmful.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341831.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

光纤收发器测试方法大全

光纤收发器产品一般应用在以太网电缆无法覆盖、必须使用光纤来延长传输距离的实际网络环境中,且通常定位于宽带城域网的接入层应用;如:监控安全工程的高清视频图像传输。我们在使用光纤收发器的过程中,不可避免的会遇到一些问题&a…

Spring Boot:构建一个RESTful Web应用程序

介绍: REST代表表示状态传输 ,是API设计的体系结构指南。 我们假设您已经具有构建RESTful API的背景。 在本教程中,我们将设计一个简单的Spring Boot RESTful Web应用程序,公开一些REST端点。 项目设置: 让我们首先通…

光纤收发器具体是怎么分类的?

现如今,随着光纤收发器产品的多样化发展,其分类方法也各异,但各种分类方法之间又有着一定的关联,那么,光纤收发器具体是怎么分类的呢?接下来就由杭州飞畅地 小编来为大家详细介绍下吧! 按速率来…

光纤收发器的分类介绍

现如今,国外和国内生产光纤收发器的厂商很多,产品线也极为丰富,主要有深圳三旺通信、光路科技、瑞斯康达、烽火、飞畅、博威、德胜、Netlink、迅捷、腾达等。时下由于国内各大运营商正在大力建设小区网、校园网和企业网,因此光纤收…

java 编译 器 ide_在没有IDE的情况下编译和运行Java

java 编译 器 ide最近一个名为“ 不使用IDE编译Java软件包 ”的Java subreddit线程提出了一个问题:“是否有一个命令将软件包内的一组Java文件编译到一个单独的文件夹中(以下简称为bin),以及如何我会去运行新的类文件吗&#xff1…

光纤收发器的工作原理以及使用方法

关于光纤收发器的工作原理以及使用方法这块,在这里飞畅科技的小编做了专门的整理,首先,我们来了解下什么是光纤收发器,光纤收发器是一种将短距离的双绞线电信号和长距离的光信号进行互换的以太网传输媒体转换单元,在很…

Spring Boot登录选项快速指南

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。 在本文中,您将研究使用Spring Boot 2.1实现登录功能的各种选项。 您将从最…

光纤收发器的故障处理

在之前,我们详细地介绍了光纤收发器的分类,我们了解到光纤收发器有单模、多模之分,单纤多纤之分,但是不管光纤收发器是怎么分类的,其故障的判断方法基本是一样的,总结起来光纤收发器所会出现的故障有&#…

光纤收发器怎么使用?

在网络建设及应用中,由于网线最大的传输距离一般为100米,因此布建远距离传输网络的时候不得不使用光纤收发器等中继设备。光纤收发器一般应用在以太网电缆无法覆盖、必须使用光纤来延长传输距离的实际网络环境中。那么,光纤收发器该如何使用呢…

光纤收发器通常具有哪些特点?

光纤收发器,是一种将短距离的双绞线电信号和长距离的光信号进行互换的以太网传输媒体转换单元,在很多地方也被称之为光电转换器,其产品一般应用在以太网电缆无法覆盖、必须使用光纤来延长传输距离的实际网络环境中,且通常定位于宽…

光纤收发器的实际应用范围介绍

众所周知,光纤收发器的有很多不同的分类,种类很多,在实际使用中大多注意的是按光纤接头不同而区分的类别:SC接头光纤收发器和FC/ST接头光纤收发器。接下来小编就来为大家介绍下光纤收发器的具体应用范围有哪些,想要了解…

光纤收发器的优势介绍

提到光纤收发器,人们常常不免会将光纤收发器与带光口的交换机来进行比较,下面咱们就主要来谈一下光纤收发器相对于光口交换机的优势。想要了解的朋友就一起来看看吧! 首先,光纤收发器和普通交换机在价格上远远比光口交换机便宜&a…

Selenium脚本编写技巧和窍门

如果您刚刚开始学习硒,则以下技巧和窍门将成为您的救星。 这些技巧和窍门具有您可能会忘记的所有基本知识,将帮助您记住所有这些。 您只需浏览一下它们,几秒钟后您就会了解所有内容。 让我们一一看一下所有的技巧和窍门。 创建Webdriver实例…

光纤收发器在使用过程中有哪些需要注意的事项?

光纤收发器的种类非常丰富,而在实际使用中大多是按照光纤接头不同进行区分,SC接头光纤收发器和FC/ST接头光纤收发器。今天,飞畅科技的小编就带大家来详细了解下光纤收发器在使用过程中需要注意的事项有哪些?一起来看看吧&#xff…

[渝粤教育] 南通大学 电路分析 参考 资料

教育 -电路分析-章节资料考试资料-南通大学【】 随堂测验:关联方向和非关联方向判断 1、【填空题】图中所示的电压源电压、电流i参考方向为 方向,电流源电压u、电流i参考方向为 方向。 A、 参考资料【 】 随堂测验:电源功率计算及判断 1、【填…

光纤收发器和协议转换器之间有哪些区别?

在通信网络领域,我们经常会用到光纤收发器和协议转换器,但对此不是很了解的朋友,往往可能会将二者搞混淆。那么,关于光纤收发器与协议转换器之间有什么区别呢?接下来就跟随杭州飞畅的小编一起来看看吧! 光…

光纤收发器结构介绍和故障解决

光纤收发器是一款高集成度的设备,最多可集成14台光纤收发器并进行统一供电,结构简单,便于管理和维护。光纤收发器包括百兆/千兆,单纤/双纤、单模/多模等多种规格。光纤收发器支持每台光纤收发器的热插拔操作,使用非常灵…

[渝粤教育] 四川信息职业技术学院 高频电子技术 参考 资料

教育 -高频电子技术-章节资料考试资料-四川信息职业技术学院【】 无线通信系统 1、【单选题】下列表述正确的是( ) A、低频信号可直接从天线上有效地辐射 B、低频信号必须装载到高频信号上才能有效地辐射 C、低频信号和高频信号都不能从天线上有效地辐射…

[渝粤教育] 四川农业大学 理论力学 参考 资料

教育 -理论力学-章节资料考试资料-四川农业大学【】 第2讲 单元测试 1、【单选题】以下说法中错误的是( ) A、理论力学是研究物体机械运动一般规律的科学。 B、理论力学与物理中力学部分的主要区别在于理论力学的研究对象和研究方法更加面向工程实际。 C、刚体是理论力学中的重…

光纤收发器怎么连接?光纤收发器连接方式解析

光纤收发器将以太网中的连接介质转换为光纤,由于光纤的低损耗、高抗电磁干扰性,从而使网络传输距离从200米扩展到2公里甚至几十公里,乃至于上百公里的同时,也使数据通讯质量有了较大提高。光纤收发器使服务器、中继器、集线器、终…