不可变类成员应该具有访问器方法还是允许是公共的



我有一个关于最佳设计实践的问题。我一直试图在我的项目中构建更多不可变的组件,因为我读到它们从长远来看更容易维护,并希望对此进行测试。

当你有一个具有不可变数据成员的类时,比如

public/private final int importantNumber = 3;

int应该仍然被声明为private并给定一个访问器方法,还是因为它的韵母,允许直接访问并将其公开有什么困难?我看不出它有任何问题被公开,因为你无法更改它。

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

还是这仅仅是一个偏好问题,会引发一场宗教战争?由于有很多关于从类内部访问数据成员的问题,我想明确一点,我是在向另一个试图获取值的外部类询问。

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

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

将事情公开,突然之间,(内部)实现细节可能会泄露到其他代码中!当然:如果数据是可变的,那只会打开一个真正的蠕虫罐头。

但是,即使是一个简单的if (someObject.someField == whatever) then do this else do that也可能很快变成一个巨大的问题。假设您在庞大的项目中有10、50、100个不同的地方有这些代码。

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

注意:隐藏字段并为其提供访问器方法"稍微"好一点。因为if (someObject.someMethod() == ...)会导致相同的问题。更糟糕的是:现在你决定someMethod()应该做一些不同的事情,来解决一个特定的问题。但是,您确定该方法调用的其他99用法在该更改后可以正常工作吗?!

最后需要注意的是:Java9引入了模块概念,所以您现在终于可以拥有一些公共的东西,但在模块之外仍然不可用。但这更多的是一个理论上的附录,我仍然会遵循基本规则,除非我有充分的理由这样做,否则不要公开。如果你想访问这些信息,比如说单元测试,那么包保护的getter应该可以。

将final字段声明为public和使用public getter将其私有之间没有实际区别。

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

更明确地说,这两种选择都是错误的。字段不应该是公共的,也不应该有getter但是,如果你做了其中一个,另一个同样错误。希望能有所帮助:)

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

但是,根据OOP中的封装原则,定义公共或私有的重要对象,即您必须声明一个获取该字段的方法,直到稍后您可以轻松地跟踪该对象需要的位置以及哪个类需要该值。

最新更新