“通过引用”编辑对象的好习惯?
Posted
技术标签:
【中文标题】“通过引用”编辑对象的好习惯?【英文标题】:Good practice to edit objects "by reference"? 【发布时间】:2011-03-16 06:41:01 【问题描述】:假设我有一个名为Superstar
的类型。现在我想要一个方法来完成一些工作并编辑Superstar
对象的一些属性。
这里有两种方法可以实现这一点。方式 1 如下:
private Superstar editSuperstar(Superstar superstar)
....
superstar.setEdited(true);
return superstar;
...
superstar = editSuperstar(superstar);
方法 2 是这样的:
private void editSuperstar(Superstar superstar)
....
superstar.setEdited(true);
...
editSuperstar(superstar);
这两种可能的方法中的哪一种被认为是“最佳做法”?第一个,还是第二个伪“通过引用”?
【问题讨论】:
【参考方案1】:在您的情况下,第二种形式更可取,因为您可以直接更改其中一个超级明星属性 (edited
)。但是,如果您有一个使用 superstar 对象的方法并返回它的更新版本(不更改初始版本),那么第一种形式将受到我的青睐。
最后,由于这两个例子都只使用了 Superstar 对象,它们应该是 Superstar 类的成员方法。
【讨论】:
这晚了,但是第二种方法并没有直接编辑外面的superstar
。它创建superstar
的本地化版本,并且从不更改任何外部对象的属性。
@Jon 你为什么这么说?这里没有任何东西支持这种说法,不是吗?【参考方案2】:
使用方式 2,除非您正在创建一个“构建器”类,您打算在其中链接调用。例如:
MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build();
【讨论】:
您的示例完全不同,它更说明了从 setter 方法返回“this”而不是“void”以允许链接 setter 调用的想法...【参考方案3】:第一种形式具有欺骗性。它给人的印象是一个对象被传入,该对象被复制,然后该副本被更改并返回。
“最佳实践”是使用第一种形式,但实际执行隐含的操作(将更改应用于副本,然后返回)。不可变对象通常应该比可变对象更受欢迎,除非它们是大块的东西,复制起来很昂贵,在这种情况下,你应该支持第二种形式。
【讨论】:
【参考方案4】:第一种方法的问题是如果你这样使用它:
Superstar edited = editSuperstar(originalSuperstar);
这也会修改原来的Superstar,在我看来,这是违反直觉的......
因此,如果您修改传递的对象,则更喜欢第二个;如果您返回对象的新副本,则更喜欢第一个。
对于这个特殊的示例,您可以简单地向 Superstar 类添加一个编辑方法...
【讨论】:
【参考方案5】:如果您返回仅更改了某些字段的同一个实例,那么第一种形式对于 API 客户端来说会令人惊讶。人们会期望在不更改原始实例的情况下获得修改后的副本。
因此,如果您不返回副本,请使用第二种形式,如果您返回,请使用第一种形式(并考虑在这种情况下使 Superstar
不可变)。
【讨论】:
以上是关于“通过引用”编辑对象的好习惯?的主要内容,如果未能解决你的问题,请参考以下文章