这是代码:
class A{
prop1, prop2, prop3, prop4, ...
private A(ABuilder b){
this.prop1 = b.prop1;
...
}
A changeProp2(){
//easiest way to return new immutable A?
}
class ABuilder{
withProp1()
withProp2()
withProp3()
...
build()
}
}
A a = new ABuilder().withProp1().withProp2().build();
A newA = a.changeProp2();
我有一个不变的对象(在这种情况下为A
),该对象是使用生成器ABuilder
构造的。现在,当我想从现有的复杂A对象中新建A对象时,就我而言,可以调用方法changeProp2()
。此方法应复制对象a
的所有内部属性,仅将property2更改为新值,然后返回新对象newA
。
最好的方法是什么?
我到目前为止发现的选项是:
在changeProp2()
方法内部,我可以复制所有属性-但这似乎太多了,并且如果将来有changeProp3()
方法,也无法重用。
//option1
A changeProp2(){
return new ABuilder().withProp1(this.prop1).withProp2("newProp2")....build();
}
将复制构造函数添加到Builder中,它将使用现有对象A中的值来初始化Builder,如下所示:
//option2
class ABuilder{
ABuilder(A a){
this.prop1 = a.prop1;
...
}
}
A changeProp2(){
return new ABuilder(this).withProp2("newProp2").build();
}
在这种情况下,这对我来说似乎更合理。
还有更多选择吗?
答案 0 :(得分:1)
您可以创建诸如A
之类的方法来返回changeProp2
的构建器,而不是从createCopyFrom
返回一个完整的A
值。例如:
public class A {
private final String prop1;
private final String prop2;
private final String prop3;
public A(String prop1, String prop2, String prop3) {
this.prop1 = prop1;
this.prop2 = prop2;
this.prop3 = prop3;
}
public ABuilder createCopyFrom() {
return new ABuilder()
.withProp1(prop1)
.withProp2(prop2)
.withProp3(prop3);
}
// ...getters...
}
public class ABuilder {
private String prop1;
private String prop2;
private String prop3;
public ABuilder withProp1(String prop1) {
this.prop1 = prop1;
return this;
}
public ABuilder withProp2(String prop2) {
this.prop2 = prop2;
return this;
}
public ABuilder withProp3(String prop3) {
this.prop3 = prop3;
return this;
}
public A build() {
return new A(prop1, prop2, prop3)
}
}
一些重要的注意事项:在上面的示例中,我对ABuilder
使用了fluent interface,但这不是必需的。它使从ABuilder
返回createCopyFrom
更加容易,但是如果ABuilder
方法不返回this
,也可以轻松完成。相反,您将设置每个属性(例如withProp1
,withProp2
等),然后按以下方式返回构建器:
public ABuilder createCopyFrom() {
ABuilder builder = new ABuilder();
builder.withProp1(prop1)
builder.withProp2(prop2)
builder.withProp3(prop3);
return builder;
}
此外,如果您想使用诸如changeProp2
之类的方法,则可以利用createCopyFrom
方法来仅更改感兴趣的属性:
public class A {
// ...same methods and fields as before...
public A changeProp2(String prop2) {
return createCopyFrom().withProp2(prop2).build();
}
}