在我的对象中包含二传手是否是一种好习惯,即使我知道我永远不会需要它



今天出现了一个有趣的问题。为我知道在构造函数之后永远不需要重新设置的字段提供出色的二传手是一种好的做法吗?

附言我当然理解使用私人场地和getter与公共领域的原因,这是有道理的,但是如果我不打算使用它,我真的应该做一个二传手吗?

P.P.S.特指Java,尽管什么平台并不重要。

通过不创建 setter 而只允许通过构造函数设置字段,您已经创建了一个不可变的字段。创建类的实例后,该值将永远不会更改。

注意:如果您的 getter 返回的值本身是可变的,则上述语句将不成立。比如说,如果返回 ArrayList 的实例,有人可以使用该引用在该列表中添加和删除项目。看看java.util.Collections.unmodifiableList来解决这个问题。如果您将其在 getter 中返回,即使是java.util.Date也可以更改。要解决这个问题,你可以使用JodaTime(或其他类似的第三方日期类(,或者等待Java 8。

以我的拙见(以及其他人并不总是那么谦虚(的观点,不变性是一件好事,它使软件的错误更少,更容易维护。

这取决于。

如果您的类是导出 API 的一部分,并且您有理由相信您的 API 的客户端将有机会使用资源库,那么包含一个资源库可能是很有意义的。

不过,这是关于getters和setters的真相。

如果您的类具有它们,那么您的类是可变的。 可变数据和可变对象就是它们。 如果您的设计意图指定此 API 将始终是单线程的,则没有问题。

但是,即使在单线程应用程序中,也应尽可能创建不可变对象。 不可变对象的缺点是 getter 和 setter 在其中没有角色(** 请参阅注释(。

折衷方案是构建器模式(Bloch, et al. Effective Java 2nd Ed.(。 在此模式中,您可以使用可变的帮助程序对象来设置对象的字段...然后,当您准备就绪时,您的帮助程序对象将使用您设置的数据来创建所需对象的不可变实例。

当您的需求很简单并且无需担心争用或并发时,请使用可变对象。 但请记住,对象的可变性越强,就越难推理其状态。 而且,对其状态进行推理越困难,强制不变和维护安全性的潜在难度就越大。 一个只能有一个状态的对象几乎可以解决所有这些问题。 特别是如果你的类是一个值类,你应该尽可能尝试创建不可变的对象。

(**( 注意:当然,可以为不可变类设置设置器。 在这种情况下,setter 实例化一个新的、不可变的对象,从而保持其不变性。 String 类依赖于此策略。

为我知道在构造函数之后永远不需要重新设置的字段创建一个 setter 是一种很好的做法吗?

如果你事先知道这一点,那么一定要把它写在你的代码中。将该字段设为final,然后您将不会有任何疑问,因为编译器本身不会允许您定义 setter。

在我看来,这避免了编写方法">因为它可能是预期的">,并且也是保持代码干净和可验证的一步。您按原样声明事物,这也消除了测试值不变性的需要。

相关内容

最新更新