Java:不可变类的伪设置器方法

杰森S:

假设我在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对象。但是,调用构造函数或创建构建器或其他方法很麻烦。因此,对我而言,最好提供此方法以方便编写客户端脚本。

aioobe:

原始文章: 不可变的设置者:命名约定(来自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(...)FontJava API中的不可变类遵循此模式。如果要使用例如特定大小的字体创建新字体

Font newFont = font.deriveFont(newSize);

Font上课开始就上课了。到目前为止,这种约定并不十分普遍。

不可变对象是操作数

当不可变对象本身是转换的操作数时,它实际上不是传统意义上的设置器,因此不需要为该方法添加前缀。例如…

BigDecimal newBigDec = bigDec.multiply(BigDecimal.TEN);

…具有与设置器相同的签名,但multiply显然比其他任何方法都更好。

同样的,String.substringPath.resolve,等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章