关山难越,谁悲失路之人;萍水相逢,尽是他乡之客。
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程教程 > 技术文章 > 正文

新来个技术总监,禁止我们使用Lombok

guanshanw 2023-09-17 17:32 39 浏览 0 评论

我有个学弟,在一家小型互联网公司做 Java 后端开发,最近他们公司新来了一个技术总监。

图片来自 Pexels

这位技术总监对技术细节很看重,一来公司之后就推出了很多"政策",比如定义了很多开发规范、日志规范、甚至是要求大家统一使用某一款 IDE。

但是这些都不是我这个学弟和我吐槽的点,他真正和我吐槽的是,他很不能理解,这位新来的技术总监竟然禁止公司内部所有开发使用 Lombok。但是又没给出十分明确的,可以让人信服的理由。

于是他来找我聊天,问我这个要求到底是否合理。关于这个事情,我认为这位技术总监的出发点是好的,但是做法未免有些极端。

之所以说出发点是好的,是因为使用 Lombok 确实会带来很多问题,而且我个人在工作中也基本不主动使用。

之所以说不主动使用,那是因为有些同事的代码还是使用了的,所以我也被迫的要安装 Lombok 的插件。

既然聊到这个话题,就简单说说我的一些看法。

Lombok 有什么好处?

Lombok 是一款非常实用 Java 工具,可用来帮助开发人员消除 Java 的冗长代码,尤其是对于简单的 Java 对象(POJO)。它通过注释实现这一目的。

如果大家对于 Lombok 比较了解的话,可以先跳过这一段,直接往后看,如果不是很熟悉的话,可以简单了解一下。

想在项目中使用 Lombok,需要三个步骤:

①IDE 中安装 Lombok 插件

目前 Lombok 支持多种 IDE,其中包括主流的 Eclipse、Intellij IDEA、Myeclipse 等都是支持的。

在 IDEA 中安装方式如下:

②导入相关依赖

Lombok 支持使用多重构建工具进行导入依赖,目前主要支持 maven、gardle、ant 等。

如使用 maven 导入方式如下:

<dependency>?????<groupId>org.projectlombok</groupId>?????<artifactId>lombok</artifactId>?????<version>1.18.12</version>?????<scope>provided</scope>?</dependency>?


③代码中使用注解

Lombok 精简代码的方式主要是通过注解来实现,其中常用的有 @Data、@Getter/@Setter、@Builder、@NonNull 等。

如使用 @Data 注解,即可简单的定义一个 Java Bean:

import?lombok.Data;?@Data?public?class?Menu?{?????private?String?shopId;?????private?String?skuMenuId;?????private?String?skuName;?}?

使用 @Data 注解在类上,相当于同时使用了 @ToString、@EqualsAndHashCode、@Getter、@Setter 和 @RequiredArgsConstrutor 这些注解,对于 POJO 类十分有用。

即自动帮忙给例子中的 Menu 类中定义了 toString、Getter、Setter 等方法。

通过上面的例子,大家可以发现,我们使用 @Data 注解大大减少了代码量,使代码非常简洁。这也是很多开发者热衷于使用 Lombok 的主要原因。

另外,关于 Lombok 的使用,不同人有不同的看法,因为很多人都使用过 Lombok,对于他的优点都比较了解,所以接下来我们重点说一下 Lombok 的使用会带来哪些问题。

Lombok 有什么坏处?

强 X 队友

因为 Lombok 的使用要求开发者一定要在 IDE 中安装对应的插件。

如果未安装插件的话,使用 IDE 打开一个基于 Lombok 的项目的话会提示找不到方法等错误。导致项目编译失败。

也就是说,如果项目组中有一个人使用了 Lombok,那么其他人就必须也要安装 IDE 插件。否则就没办法协同开发。

更重要的是,如果我们定义的一个 jar 包中使用了 Lombok,那么就要求所有依赖这个 jar 包的所有应用都必须安装插件,这种侵入性是很高的。

代码可读性,可调试性低

在代码中使用了 Lombok,确实可以帮忙减少很多代码,因为 Lombok 会帮忙自动生成很多代码。

但是这些代码是要在编译阶段才会生成的,所以在开发的过程中,其实很多代码是缺失的。

在代码中大量使用 Lombok,就导致代码的可读性会低很多,而且也会给代码调试带来一定的问题。

比如,我们想要知道某个类中的某个属性的 getter 方法都被哪些类引用的话,就没那么简单了。

有坑

因为 Lombok 使代码开发非常简便,这就使得部分开发者对其产生过度依赖。

在使用 Lombok 过程中,如果对于各种注解的底层原理不理解的话,很容易产生意想不到的结果。

举一个简单的例子,我们知道,当我们使用 @Data 定义一个类的时候,会自动帮我们生成 equals() 方法 。

但是如果只使用了 @Data,而不使用 @EqualsAndHashCode(callSuper=true) 的话,会默认是 @EqualsAndHashCode(callSuper=false)。

这时候生成的 equals() 方法只会比较子类的属性,不会考虑从父类继承的属性,无论父类属性访问权限是否开放。这就可能得到意想不到的结果。

影响升级

因为 Lombok 对于代码有很强的侵入性,就可能带来一个比较大的问题,那就是会影响我们对 JDK 的升级。

按照如今 JDK 的升级频率,每半年都会推出一个新的版本,但是 Lombok 作为一个第三方工具,并且是由开源团队维护的,那么他的迭代速度是无法保证的。

所以,如果我们需要升级到某个新版本的 JDK 的时候,若其中的特性在 Lombok 中不支持的话就会受到影响。

还有一个可能带来的问题,就是 Lombok 自身的升级也会受到限制。

因为一个应用可能依赖了多个 jar 包,而每个 jar 包可能又要依赖不同版本的 Lombok。

这就导致在应用中需要做版本仲裁,而我们知道,jar 包版本仲裁是没那么容易的,而且发生问题的概率也很高。

破坏封装性

以上几个问题,我认为都是有办法可以避免的。但是有些人排斥使用 Lombok 还有一个重要的原因,那就是他会破坏封装性。

众所周知,Java 的三大特性包括封装性、继承性和多态性。

如果我们在代码中直接使用 Lombok,那么他会自动帮我们生成 getter、setter 等方法,这就意味着,一个类中的所有参数都自动提供了设置和读取方法。

举个简单的例子,我们定义一个购物车类:

@Data?public?class?ShoppingCart?{??????//商品数目?????private?int?itemsCount;??????//总价格?????private?double?totalPrice;??????//商品明细?????private?List?items?=?new?ArrayList<>();?}?

我们知道,购物车中商品数目、商品明细以及总价格三者之前其实是有关联关系的,如果需要修改的话是要一起修改的。

但是,我们使用了 Lombok 的 @Data 注解,对于 itemsCount 和 totalPrice 这两个属性,虽然我们将它们定义成 private 类型,但是提供了 public 的 getter、setter 方法。

外部可以通过 setter 方法随意地修改这两个属性的值。我们可以随意调用 setter 方法,来重新设置 itemsCount、totalPrice 属性的值,这也会导致其跟 items 属性的值不一致。

而面向对象封装的定义是:通过访问权限控制,隐藏内部数据,外部仅能通过类提供的有限的接口访问、修改内部数据。所以,暴露不应该暴露的 setter 方法,明显违反了面向对象的封装特性。

好的做法应该是不提供 getter/setter,而是只提供一个 public 的 addItem 方法,同时去修改 itemsCount、totalPrice 以及 items 三个属性。

总结

本文总结了常用的 Java 开发工具 Lombok 的优缺点。

优点是使用注解即可帮忙自动生成代码,大大减少了代码量,使代码非常简洁。

但是并不意味着 Lombok 的使用没有任何问题,在使用 Lombok 的过程中,还可能存在对队友不友好、对代码不友好、对调试不友好、对升级不友好等问题。

最重要的是,使用 Lombok 还会导致破坏封装性的问题。虽然使用 Lombok 存在着很多方便,但是也带来了一些问题。

但是到底建不建议在日常开发中使用,我其实保持一个中立的态度,不建议大家过度依赖,也不要求大家一定要彻底不用。

只要大家在使用的过程中,或者评估要不要在代码中引入 Lombok 之前,在想到他的优点的同时,能够考虑到他给代码带来的问题的,那么本文的目的也就达到了!

相关推荐

七条简单命令让您玩转Git
七条简单命令让您玩转Git

凭借着出色的协作能力、快速部署效果与代码构建辅助作用,Git已经得到越来越多企业用户的青睐。除了用于开发商业及消费级应用之外,众多科学及政府机构也开始尝试使用这...

2023-10-07 12:14 guanshanw

基本完整的关于Git分支branch的操作
基本完整的关于Git分支branch的操作

Git使用背景项目中要用到dev或者其他分支开发完代码,需要将该分支合并到master的需求操作步骤下面以dev名称为lex为分支名为例来操作一遍客户端操作:...

2023-10-07 12:14 guanshanw

Git 进阶(合并与变基)
Git 进阶(合并与变基)

在Git中整合来自不同分支的修改主要有两种方法:合并(merge)以及变基(rebase)合并(merge)merge流程图merge的原理是找到这两个分...

2023-10-07 12:13 guanshanw

Git学习笔记 003 Git进阶功能 part5 合并(第一部分)

合并(merge)是很常用的操作。尤其是一个庞大的很多人参与开发的企业级应用。一般会设定一个主分支,和多个副分支。在副分支开发完成后,合并到主分支中。始终保持主分支是一个完整的,稳定的最新状态的分支。...

非标题党,三张图帮你理解git merge和git rebase的区别
非标题党,三张图帮你理解git merge和git rebase的区别

初始场景:基于正常的开发分支修改几个小bug,然后在合并到开发分支上。gitmergegitcheckoutfeaturegitmergeho...

2023-10-07 12:13 guanshanw

git 初次使用(01)
git 初次使用(01)

先从github上克隆代码下来:使用vscode克隆代码如下图,填写上github仓库地址:vscode有时候克隆代码速度比较慢,可以用命令行方式克隆gitc...

2023-10-07 12:12 guanshanw

Git 远程操作

4.Git远程操作命令说明gitremote远程版本库操作gitfetch从远程获取版本库gitpull下载远程代码并合并gitpush上传远程代码并合并4.1远程版本库操作gitre...

Git常用命令-总结
Git常用命令-总结

创建git用户$gitconfig--globaluser.name"YourName"$gitconfig--globaluser.em...

2023-10-07 12:12 guanshanw

git中删除从别人clone下来项目的git信息,并修改为自己的分支

如果你从别人的Git存储库中克隆了一个项目,并想要删除与该存储库相关的Git信息,并将其修改为你自己的分支,则可以执行以下步骤:使用gitclone命令克隆存储库:gitclone<u...

git系列-回滚和放弃本地修改

回滚历史提交就是reset的功能。这种情况是已经提交远程仓库,需要回滚到之前的提交。gitreset--hardcommitId//注:强制提交后,当前版本后面的提交版本将会删掉!gi...

GIT使用小技巧大全
GIT使用小技巧大全

在大型软件工程的开发过程中,版本控制是无法绕过去的;目前来说,最火的版本控制软件就是GIT了。早两年SVN比较火,不过被大神linus喷了几次后,就日落西山了,...

2023-10-07 12:11 guanshanw

git相关命令-上
git相关命令-上

这些命令都是看了文档后,个人觉得比较有用的一些,展示给大家。回到远程仓库的状态抛弃本地所有的修改,回到远程仓库的状态。gitfetch--all&...

2023-10-07 12:10 guanshanw

Git命令行接口:掌握Git的必备技能
Git命令行接口:掌握Git的必备技能

Git是一款强大的分布式版本控制工具,它支持命令行界面操作。熟练掌握Git命令行接口,是开发者使用Git的必备技能之一。在这篇文章中,我们将介绍Git命令行接口...

2023-10-07 12:10 guanshanw

Git命令详解
Git命令详解

相信各位小伙伴们应该都对git有一些了解,毕竟作为代码管理的神器,就算不是IT行业的小伙伴肯定也或多或少的听说过一些。今天就来和小伙伴们分享一下自己总结的常用命...

2023-10-07 12:10 guanshanw

工作7年收集到的git命令
工作7年收集到的git命令

概念git中的术语解释:仓库也叫版本库(repository)stage:暂存区,add后会存到暂存区,commit后提交到版本库git安装linux...

2023-10-07 12:10 guanshanw

取消回复欢迎 发表评论: