假设我在Java中有一个Foo类,它具有不变的数据:
class Foo {
final private int x;
public int getX() { return this.x; }
final private OtherStuff otherstuff;
public Foo(int x, OtherStuff otherstuff) {
this.x = x;
this.otherstuff = otherstuff;
}
// lots of other stuff...
}
现在,我想添加一个实用程序方法,该方法创建具有相同状态但具有新值x的“同级”值。我可以这样称呼setX()
:
class Foo
{
...
Foo setX(int newX) { return new Foo(newX, this.otherstuff); }
...
}
但是的语义setX()
不同于可变bean对象的标准setter约定,因此某种程度上感觉不对。
此方法的最佳名称是什么?
我应该把它withX()
或者newX()
还是其他什么东西?
编辑:在我的情况下,其他优先级:我拥有脚本客户端(通过JSR-223和导出的对象模型),可以轻松获取Foo
对象。但是,调用构造函数或创建构建器或其他方法很麻烦。因此,对我而言,最好提供此方法以方便编写客户端脚本。
原始文章: 不可变的设置者:命名约定(来自Programming.Guide)
withX(...)
这是不可变设置器的事实上的标准命名约定。例如,这是Immutables框架生成的setter的默认名称。这是一个例子:
Foo newFoo = foo.withX(1047);
有一个@Value.Style
选项可以更改此模式,但选项本身称为with="..."
,它强调了默认约定。
作为最广泛的惯例,很容易找到这样的例子。Guava和Java 时间包是两个。
x(...)
另一种方法是根本没有前缀。您可以在Immutables框架生成的示例构建器中看到以下内容:
Foo foo = ImmutableFoo.builder()
.x(1047)
.y("Hello World")
.build();
如果直接在不可变的类上使用此方法(即不涉及任何构建器),通常会将其作为getter的重载:
Foo newFoo = foo.x(5); // setter - one argument
int x = newFoo.x(); // getter - no arguments
例如,该约定用于Java Spark框架。
setX(...)
某些API使用与可变类中的setter相同的命名约定。这有一个明显的缺点,那就是您刚接触代码库时可能会感到惊讶。工作BigInteger
和写作...
bigInt.setBit(2);
……例如,这将是一个错误,因为返回的对象将被丢弃。使用这种命名模式,您必须习惯于编写
BigInteger newBigInt = bigInt.setBit(2);
deriveX(...)
要突出显示新值是从现有对象派生的事实,可以使用deriveX(...)
。Font
Java API中的不可变类遵循此模式。如果要使用例如特定大小的字体创建新字体
Font newFont = font.deriveFont(newSize);
从Font
上课开始就上课了。到目前为止,这种约定并不十分普遍。
当不可变对象本身是转换的操作数时,它实际上不是传统意义上的设置器,因此不需要为该方法添加前缀。例如…
BigDecimal newBigDec = bigDec.multiply(BigDecimal.TEN);
…具有与设置器相同的签名,但multiply
显然比其他任何方法都更好。
同样的,String.substring
,Path.resolve
,等。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句