内联脚本被视为是有害的_数据类被认为有害

内联脚本被视为是有害的

这篇博客文章解释了从我参与的项目之一中删除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添加字段是错误的另一个常见来源。
使用代码生成时,我们消除了这些错误源。 此外,不存在的代码也不会影响我们的测试覆盖率统计信息。 这并不意味着它不需要测试。

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

删除:300行
新增:1200线

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

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

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

双重痛苦

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

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

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

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

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

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

内联脚本被视为是有害的

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

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

相关文章

win10可用空间变成未分配_教你两种方法有效利用Win10未分配的空间 - 易我科技...

Haley 于2020/08/24更新 磁盘分区管理摘要文中介绍了两种方法充分利用Windows10未分配空间,分别为1)格式化Win10未分配空间来创建新的分区,2)在分区上添加未分配空间。我的Win 10计算机上有一个大小99GB的未分配空间 :「我在Windows计算机上安装了两个硬…

selenium编写脚本_Selenium脚本编写技巧和窍门

selenium编写脚本如果您刚刚开始学习Selenium,则以下技巧和窍门将成为您的救星。 这些技巧和窍门具有您可能会忘记的所有基本知识,将帮助您记住所有这些。 您只需浏览一次,几秒钟后您便会了解所有内容。 让我们一一看一下所有的技巧和窍门。 …

div和div之间画横线_HTML如何在两个div标签中间画一条竖线

近日在画一个界面的时候,遇到一个需求:在界面当中画一条竖线,且这条竖线在高度上需要自动占满整个父div(即这条竖线的高度和两个div中较高的一个等高)。往常我们画一条横线直接用标签即可,当画一条竖线的时候发现找不到标签。在网…

静态类型/静态分派/动态分派/单分派/多分派

文章目录静态类型/实际类型方法解析静态分派动态单分派参考静态类型/实际类型 Human woman new Woman(); // Human就是静态类型,其实就是变量编译时类型,Woman就是实际类型 Man man new Man(); // 静态类型和实际类型都是Man方法解析 Class 文件的编…

jvm回收垃圾_没有垃圾回收的JVM

jvm回收垃圾JVM社区不断增加新的GC,最近又添加了一个新的GC,它被称为Epsilon ,是非常特殊的一个。 Epsilon仅分配内存,但不会回收任何内存。 看起来好像不执行任何垃圾回收的GC用途是什么。 这种类型的垃圾收集器有特殊用途&…

C打印函数printf的一种实现原理简要分析

【0】README 0.1)本文旨在对 printf 的 某一种 实现 原理进行分析,做了解之用;0.2) vsprintf 和 printf.c 的源码,参见 https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/p309 【1】pr…

wireshark提取流量包中的文件_[技术]Wireshark抓取的数据包提取文件

0x00 简介本期主要会教大家如何从流量中还原出来文件。下面我将会用多种办法来讲解。使用系统:Kali Linux0x01 tcpxtract工具网络流量提取文件(方法1)Kali Linux默认没有安装该工具,需要自己安装安装命令:sudo apt install tcpxtract使用方法…

java设计模式适配器模式_Java中的适配器设计模式

java设计模式适配器模式适配器设计模式是一种结构设计模式 ,可以帮助我们连接到通过不同接口公开相似功能的旧版或第三方代码。 适配器的现实世界是我们用来将USB电缆连接到以太网端口的类比。 在设计一个面向对象的应用程序时,当我们的客户期望一个特…

技术路线的选择重要但不具有决定性

微软在技术上连续大动作,如果放在几年前,我相信微软粉丝们一定是欢声雷动,不过这次情况有点不太一样,在网上看到有人在抱怨微软技术更新速度太快而且四面出击,还有人扬言要改弦更张,投奔Linux或者Java阵营。…

nproc是什么意思_top/htop内容的含义

uptimeuptime命令显示了load avg,它其实是读取的/proc/uptime文件:/proc/uptime 文件cat /proc/uptime9592411.58 9566042.33第一个是系统启动了多久(单位s),第二个意思是系统启动以来,cpu idle花费的时间(单位s)。多核机器上&…

进程间通信(IPC)+进程加锁解锁

【0】README 0.1) source code and text description are from orange’s implemention of a os;0.2) for complete code , please visit https://github.com/pacosonTang/Orange-s-OS/tree/master/ipc_8 【1】看看,我们的进程代…

QA与测试到底有什么区别?

文章目录引言QA与测试的区别?QA、QC、QM的关系与区别?QA工作内容与职责引言 近期微信公众号后台有同学留言问: QA与测试的区别? QA、QC、QM的区别?以及QA的工作内容与职责。 针对这些问题我查阅了一些资料然后结合自…

java 进程运行时间_将Java类作为子进程运行

java 进程运行时间我本周需要将Java类(而不是jar)作为子进程运行。 更确切地说,我想从测试内部产生一个新进程,而不是直接在测试内部(进程内)运行它。 我不认为这是幻想或复杂的事情。 但是,这不…

划分vlan实验心得体会_思科:相同vlan,不同交换机之间的通信

实验拓扑如下:VPC 26 IP 23.1.1.3 24 VLAN20VPC 25 IP 12.1.1.2 24 VLAN10VPC1 IP 12.1.1.1 24 VLAN10VPC2 IP 23.1.1.2 24 VLAN20IOL交换机命名为SW1 先配置SW1的vlan10 和20检查SW1的vlan信息配置SW1的vlan10 和20检查SW2的vlan信息下一步将SW1和SW2连接的接口改为…

如何通过W3school学习JS/如何使用W3school的JS参考手册

文章目录学习JS对象DOM 对象HTML 对象JS 的常规类型教程学习 jQuery学习平台: W3school类似的学习平台: 菜鸟教程学习JS对象 DOM 对象 HTML 对象 JS 的常规类型 教程 学习 jQuery

快速选择

【0】README 0.1)设有一组N 个数而要确定其中第k 个最小(大)者,我们称之为选择问题; 选择问题的解法?” 解法即为 快速选择算法; 0.2) 快速选择是对 快速排序 改造而来&#xff0…

java模板方法模式_Java中的模板方法模式

java模板方法模式模板方法模式是一种行为模式,建议在超类中更一般地定义算法。 该算法是在称为模板方法的方法中定义的。 子类仅定义更具体的算法步骤的实现。 使用这种设计模式的好处是,算法后面的任何更改只会影响超类中的代码。 此外,它还…

hive 索爱_达内大数据云计算

第一阶段(Java基础)Java语言的高级特性静态导入、自动封箱拆箱、可变参数、增强for、枚举、类加载器、反射、内省、泛型、注解、动态代理回掌握Java语言的高级特性Java多线程多线程加强、线程池、Thread Local掌握Java线程池技术,掌握线程的Join、notify、notifyAll…

建立文件系统

【0】README 0.1) source code and text description are from orange’s implemention of a os and for complete code, please visit https://github.com/pacosonTang/Orange-s-OS/blob/master/orange_s_fs.tar; 0.2) 此文件系统涉及到的…

判断字符串是否为空

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>检查指定的值是不是空字符串</title><script>function test_1() {// var name document.getElementById("name").value;// ale…