LinkedBear
LinkedBear
Published on 2025-06-13 / 61 Visits
0
0

为什么人们宁可用Lombok,也不把成员设为public?

简单地说,既有设计的前瞻(有没有是你的事,用不用是我的事),又有妥协和无奈(不这么干代码就跑不起来)。

一个一个论述。

有没有是你的事,用不用是我的事

我们假定一个抽象的场景:

如果成员属性设置为public,那大概率没人会单独写getter方法了吧,直接对象.属性就行了。

但随之而来的问题是:如果这个属性在获取/赋值的时候有额外操作呢?而且这种额外操作是整个应用全局都要生效呢(例如应用中所有的身份证号、手机号在设置属性值时都要校验)?

直接对象.属性的话,那就得每个地方都要改,这改动量可想而知。

这个时候就体现出getter和setter方法的好处了。直接改这两个方法就行了,大家一起生效。

如果影响范围很广,大部分都需要改,那就默认的getter或setter方法改掉,少数直接用原值的另起一个方法(或者反过来也行)。

这个时候可能有朋友会说:不是说不让在getter和setter方法里写逻辑吗?

我的朋友,如果真照你这么说的话,那getter和setter方法的意义好像也就真的不存在了。规范是规范,别那么死板。真到了要用的时候,你还那么墨守成规,那无非两种后果:要么你多费时间还不讨好(领导可不管你的代码实现多么优雅规范,人家只看功能改好了没),要么你做不了让别人做,功劳没了还遭人蛐蛐(说不定地位还下降了,啧啧)。

类似的情况还有Service一定要写成接口,配一个几百年不出第二个兄弟的ServiceImpl),好一个超前设计。。。

还是最开始那句话:我可以不用(定制getter/setter),但你不能没有(不定义getter/setter)。不然你猜最初没有Lombok的时候,为什么大家还是老老实实用private+getter/setter。

不这么干代码就跑不起来

部分用到反射的库会去探测属性的getter/setter方法,如果属性被设置为public,那框架会认为你这个Bean设计的有问题,而不是退而求其次去试探public。

其实这也能说明,最初这些库的设计者就认为纯用public是不正常的,所以不予兼容也说得过去。

好了,现在你要用这些库了,那我请问,你是强行用public然后报错了哇哇大叫,还是识时务者为俊杰呢


提几个可能会杠的点:

1.getter/setter方法上加额外逻辑的可能性极小,所以没必要过度设计,用public类型也行。

好吧,这个说法刚好跟我上面说的Service接口配一个ServiceImpl一样,本质上属于超前设计。但是这两者又不同,private+@Data虽然绝大多数场景下的效果跟直接用public没什么区别,但是当需要Debug某个属性被读/写的情况时,在对应的实体类中显式定义getter/setter方法会更方便,直接用public修饰的我不确定能不能也这么方便。

朋友,记住一点,只要不是自己的孩子,没必要那么上心(何况有的人连自己的孩子都不上心),别的也一样。

2.为什么要直接在getter方法上扩展逻辑,写个新的getXxx不好吗?

还真不一定好,Java的内省机制会将getXxx方法反解析为实体里有一个xxx属性,然而实际上没这玩意。内省机制本身没什么毛病,但是碰上一些依赖内省机制又想反射的框架而言,那可能运行期就爆雷了。

3.实体类上不能写逻辑!

DDD:?

充血模型:?

4.Java语言就是有这种独特的风味儿,总是觉得这里以后要扩展,那里以后要改动,天天就知道幻想!

你说得对 :)


Comment