不可变的类成员是否应该具有访问器方法或允许公开?

时间:2019-01-30 14:38:17

标签: java immutability private public accessor

我对最佳设计做法有疑问。我一直试图在项目中构建更多不变的组件,因为从长远来看,它们更易于维护,并且想要对其进行测试。

当您的类具有不变的数据成员时,请说

 public/private final int importantNumber = 3;

应该将int仍然声明为私有并赋予访问器方法,还是由于其终结符,允许直接访问并将其公开的难点是什么?我看不到有任何公开问题,因为您无法更改它。

在我的情况下,不可变对象是使用传递给它的值创建的,然后将自动填充数据库中的其他对象,一切都是最终的。

这仅仅是一个偏爱问题,会引发一场宗教战争吗?由于存在关于从类内部访问数据成员的许多问题,因此我想明确地说,我是从另一个试图获取该值的外部类询问的。

3 个答案:

答案 0 :(得分:4)

公开发布允许其他代码依赖它。

数据是可变的还是不可变的都没有关系。一旦其他一些代码使自己依赖,您就可以解决将来的问题。在任何更大的项目中,这些问题迟早都会表现出来。

将事情公开,(内部)实现细节可能会泄漏到其他代码中!当然,如果这些数据是可变的,那只会打开蠕虫的 real 罐。

但是即使是简单的if (someObject.someField == whatever) then do this else do that也会很快变成一个巨大的问题。只需假设您在大型项目中的10、50、100个不同位置中都有该代码。

因此,您的默认规则是:隐藏您的信息。使事物公开例外,它的发生是因为您绝对希望您的设计采用这种方式。您的默认是为您的字段(甚至方法)提供最严格的可见性,仍然允许您实现需求。

并注意:隐藏字段并为其使用访问器方法“稍微”更好。因为if (someObject.someMethod() == ...)导致相同问题。而且(几乎)更糟:现在您决定someMethod()应该做一些不同的事情来解决一个特定的问题。但是,您确定该方法调用的 other 99种用法在此更改下可以正常工作吗?!

最后警告:Java 9引入了模块概念,因此您现在终于可以公开使用某些东西,但是仍然无法在模块外部使用。但这更多是理论上的补充,除非我有充分的理由,否则我仍然会遵循基本规则,并且不要公开任何事情。如果要访问该信息(例如进行单元测试),则应使用受程序包保护的getter。

答案 1 :(得分:1)

将最终字段声明为公共字段或将其与公共获取者私有都没有。

有很多理论上的争论,为什么拥有公共场所真的很糟糕,但是实际上没有任何实际的实践理由不这样做。是的,理论上,您可以稍后再更改吸气剂以执行其他操作,但您可能不会。即使您希望大多数人告诉您,getter都应该只返回没有其他逻辑的字段。

更清楚地说,这两种选择都是错误的。字段不应该是公共的,也不应该有吸气剂。 但是,如果您选择其中之一,则另一个同样是错误的。希望能有所帮助:)

答案 2 :(得分:0)

当您声明对象final是不可变的,没有人可以更改其值。

但是根据OOP中的封装原理,定义一个重要的对象public或private,必须声明一种获取该字段的方法,直到以后您可以轻松地跟踪到该对象的需求以及哪个类需要该值。