考虑对象封装,getters 是否应该返回不可变属性?

2022-09-02 20:58:38

当 getter 返回一个属性(例如返回其他相关对象的 a)时,该列表及其对象是否应该不可变,以防止类外部的代码在主父对象不知道的情况下更改这些对象的状态?List

例如,如果一个对象有一个 getter,它返回一个对象,那么调用该 getter 的任何代码:ContactgetDetailsListContactDetails

  1. 可以在对象不知道的情况下从该列表中删除对象。ContactDetailContact
  2. 可以在对象不知道的情况下更改每个对象。ContactDetailContact

那么,我们应该怎么做呢?我们应该只信任调用代码并返回容易可变的对象,还是走硬路,为每个可变类创建一个不可变类?


答案 1

这是一个你是否应该在代码中“防御”的问题。如果你是你的类的(唯一)用户,并且你信任自己,那么无论如何都不需要不变性。但是,如果此代码无论如何都需要工作,或者您不信任您的用户,那么使外部化的所有内容都不可变。

也就是说,我创建的大多数属性都是可变的。偶尔有一个用户搞砸了,但话又说回来,这是他/她的错,因为很明显,突变不应该通过通过getters接收的可变对象发生。


答案 2

这取决于上下文。如果列表是可变的,那么当 List 有自己的一个非常好的 API 时,用方法来改变主类的 API 是没有意义的。

但是,如果主类无法应对突变,那么您需要返回一个不可变的列表 - 并且列表中的条目本身可能也需要是不可变的。

但是,不要忘记,您可以返回一个自定义 List 实现,该实现知道如何安全地响应突变请求,无论是通过触发事件还是直接执行任何必需的操作。实际上,这是使用内部类的好时机的经典示例。