假设我有一个名为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);
这两种可能方式中的哪一种被认为是“最佳做法”?第一个,或第二个伪“引用”一个?
答案 0 :(得分:6)
在您的情况下,第二种形式是可取的,因为您直接更改了其中一个超级巨星属性(edited
)。但是,如果你有一个方法使用超级巨星对象并返回它的更新版本(不更改初始对象),第一个表单将有利于我。
最后,由于这两个示例都只使用Superstar对象,因此它们应该是Superstar类的成员方法。
答案 1 :(得分:4)
使用方式2,除非您要创建一个打算链接调用的“构建器”类。例如:
MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build();
答案 2 :(得分:4)
第一种形式具有欺骗性。它给人的印象是传入一个对象,然后复制该对象,然后更改并返回副本。
“最佳实践”是使用第一种形式,但要实际执行隐含的内容(将更改应用于副本,然后返回)。不可变对象通常应优先于可变对象,除非它们是复制成本高的大块东西,在这种情况下,你应该支持第二种形式。
答案 3 :(得分:2)
你在第一种方法遇到的问题是如果你这样使用它:
Superstar edited = editSuperstar(originalSuperstar);
这也将修改原始的超级明星,在我看来,这是违反直觉的......
因此,如果您修改传递的对象,则更喜欢第二个,如果您返回该对象的新副本,则更喜欢第一个。
对于这个特殊的例子,你可以简单地将一个编辑方法添加到Superstar类......
答案 4 :(得分:1)
如果返回仅更改了某些字段的同一实例,则第一种形式对于API客户端来说会令人惊讶。人们希望在不更改原始实例的情况下获得修改后的副本。
因此,如果您没有返回副本,请使用第二个表单,如果您这样做,请使用第一个表单(并考虑在这种情况下使Superstar
不可变)。