Joshua Bloch给出的建议之一是,类应该被设计为不可变的。
我有以下课程
public class Dividend {
public Dividend setDate(SimpleDate date) {
Dividend dividend = new Dividend(this.getStock(), this.getAmount(), date);
return dividend;
}
.....// More to go.
对于 setDate 方法,此对象不会被修改。
相反,将返回此的克隆副本及其日期字段被修改。
但是,通过判断方法名称,用户将如何知道此对象仍将保持不变?
除 setDate 之外还有更好的命名约定吗?
答案 0 :(得分:10)
如果你有setter,你的类看起来很可变,用户可能会以错误的方式使用它。他们可能会这样称呼它:
dividend.setDate(myDate);
然后惊讶为什么dividend
的日期没有改变。他们应该像这样使用它:
newDividend = dividend.setDate(myDate);
为了使API更直观,最好将setDate
方法重命名为copyWith
:
newDividend = dividend.copyWith(myDate);
或者,如果您有多个字段并且重载会令人困惑,您可以将它们称为copyWithDate
和copyWithComment
。
其他名称也是可能的,如其他答案中所述:derive
(和deriveWithDate
),或只是withDate
。
答案 1 :(得分:3)
Font
具有(a)derive
方法,用于创建从当前方法派生的新字体实例。
答案 2 :(得分:2)
我见过的许多Java库开始使用with
作为'此对象的副本的前缀,带有以下更改'。
例如:
public Dividend withDate() {
....
适合
Dividend newDividend = oldDividend.withDate(...).withAmount(...).withComment(...);
例如, JSR-310遵循这种模式(以及使用plusXxx()
和minusXxx()
作为“调整器”对象,例如,它取三角形而不是绝对值。
答案 3 :(得分:1)
你应该像String类一样实现你的类,它没有setter。可以理解的是,如果没有人可以在其上设置任何东西,它是不可改变的。 (也许你可能想让setter私有,或者你可能只想直接从你的Dividend类中设置变量)
答案 4 :(得分:-1)
这个函数只是构造函数的包装器。重载构造函数以接受要复制的完整被除数对象。否则,你可以重命名这个函数getDividend(它肯定不是一个setter)。
答案 5 :(得分:-1)
由于返回Dividend
,用户可能会知道它是一个新的Dividend
实例。即使这样,你也可以重新考虑这个名字。