一个不可变的 class 成员应该有访问器方法还是允许 public?

Should an immutable class member have an accessor method or allowed to be public?

我对最佳设计实践有疑问。我一直在尝试在我的项目中构建更多不可变组件,因为我读到它们在长期 运行 中更容易维护,并且想对此进行测试。

当你有一个包含不可变数据成员的 class 时,说

 public/private final int importantNumber = 3;

是否仍应将 int 声明为 private 并为其提供访问器方法,或者因为它是 final,允许直接访问并使其成为 public 有什么困难?我没有发现任何问题 public 因为您无法更改它。

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

或者这仅仅是一个偏好问题并且会引发宗教war?由于有很多关于从 class 内部访问数据成员的问题,我想说明一下,我是从另一个外部 class 试图获取值的。

制作东西public 允许其他 代码依赖它。

数据是可变的还是不可变的并不重要。一旦某些其他代码使自己依赖 依赖该信息,您就会引发未来的问题。在任何较大的项目中,这些问题 迟早会 显现出来。

制作东西 public,突然间,(内部)实现细节可以泄漏到其他代码中!当然:如果该数据是可变的,那只会打开一个 real 的蠕虫罐头。

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

因此,您的默认规则是:隐藏您的信息。制作 public 例外 ,它的发生是因为您绝对希望您的设计是那样的。您的 default 是为您的字段(甚至方法)提供最严格的可见性,但仍然允许您实现您的要求。

注意:隐藏字段并为其提供访问器方法只是 "slightly" 更好。因为 if (someObject.someMethod() == ...) 会导致 相同的 问题。而且(几乎)更糟:现在您决定 someMethod() 应该做一些不同的事情,以解决一个特定的问题。但是您确定该方法调用的 other 99 次使用可以很好地适应该更改吗?!

最后警告:Java 9 引入了模块概念,因此您现在终于可以拥有一些东西 public,但仍然无法从模块外部使用。但这更像是一个理论上的附录,除非我有充分的理由这样做,否则我仍然会遵循基本规则并且不做任何事情 public 。如果您想访问该信息,例如单元测试,那么一个受保护的包 getter 应该可以。

当您声明一个对象 final 是不可变的并且没有人可以更改它的值时。

但是根据OOP中的封装原则定义public或private一个重要的对象,你必须声明一个获取该字段的方法,直到以后你可以很容易地跟踪到这个对象在哪里需要哪个class 需要这个值。

声明最终字段 public 或使用 public getter 将其私有没有实际区别

有很多理论上的手摇式争论为什么拥有 public 字段真的很糟糕,但实际上没有不这样做的真正实际理由。是的,理论上您 可以 稍后更改 getter 来做一些不同的事情,但您可能不会。即使你想要,大多数人也会告诉你 getter 实际上应该只是 return 它获得的字段而无需额外的逻辑。

更清楚地说,这两个选项都是错误的。字段不应该是 public,也不应该是 getter。 但是,如果你做了其中一个,另一个同样是错误的。希望有所帮助:)