我有以下代码:
package me.immutable;
import java.util.*;
public class Immutable {
public static void main(String[] args) {
//this is immutable using builder
SimpleClass wb = new SimpleClass.Builder()
.addString("a")
.addString("b")
.addString("c")
.withWillNotChange("notchange")
.build();
//this is new immutable with changes only needed properties
//wb object remains unchanged
SimpleClass newWb = wb.withDifferentStrings(Arrays.asList("d", "e", "f"));
}
}
class SimpleClass {
private final List<String> strings;
private final SimpleObservable simpleObservable;
private final String willNotChange;
private SimpleClass(Builder builder){
this.strings = builder.strings;
this.willNotChange = builder.willNotChange;
this.simpleObservable =
builder.simpleObservable == null ?
new SimpleObservable(strings) :
builder.simpleObservable;
}
SimpleClass withDifferentStrings(List<String> strings){
return builder(this) //create new immutable object using builder
.withStrings(strings) //modify only what changes
.withSimpleObservable(simpleObservable.changeCanChange(strings))
.build();
}
Builder builder(SimpleClass sc){
return new Builder(sc);
}
static class Builder{
private List<String> strings = new ArrayList<>();
private SimpleObservable simpleObservable;
private String willNotChange;
Builder(){}
Builder(SimpleClass sc){
this.strings = sc.strings;
this.willNotChange = sc.willNotChange;
this.simpleObservable = sc.simpleObservable;
}
Builder addString(String s){
strings.add(s);
return this;
}
Builder withWillNotChange(String s){
willNotChange = s;
return this;
}
Builder withStrings(List<String> strings){
this.strings = strings;
return this;
}
private Builder withSimpleObservable(SimpleObservable simpleObservable){
this.simpleObservable = simpleObservable;
return this;
}
SimpleClass build(){
return new SimpleClass(this);
}
}
}
class SimpleObservable{
private SimpleObserver observer;
private List<String> canChange = new ArrayList<>();
public SimpleObservable(List<String> canChangeSet){
canChange.addAll(canChangeSet);
observer = new SimpleObserver(canChange);
}
private SimpleObservable(SimpleObservable so){
canChange = so.canChange;
observer = so.observer;
}
public SimpleObservable changeCanChange(List<String> canChangeSet){
//No builder so we use copy constructor to build new immutable object and not change this one
SimpleObservable o = new SimpleObservable(this);
o.canChange = canChangeSet; //update only what changes
o.observer = observer.notifyMe(o.canChange);
return o;
}
}
class SimpleObserver{
private String name;
public SimpleObserver(List<String> canChange){
this.name = canChange.get(0);
}
private SimpleObserver(SimpleObserver so){
name = so.name;
}
public SimpleObserver notifyMe(List<String> changed){
SimpleObserver o = new SimpleObserver(this);
o.name = changed.get(0);
return o;
}
}
在这里,我有三节课: SimpleClass
, SimpleObservable
以及 SimpleObserver
. SimpleClass
在内部使用生成器,我可以创建它的不可变副本,只需使用以下代码更改几个字段:
return builder(this) //create new immutable object using builder
.withStrings(strings) //modify only what changes
.withSimpleObservable(simpleObservable.changeCanChange(strings))
.build();
我怎样才能在其他两个类中使用 final
领域?目前我不使用最终的,复制构造函数的作品。
SimpleObserver o = new SimpleObserver(this);
o.name = changed.get(0); //if name is final, I could not do this
return o;
有什么选择吗 final
字段,并保持创建新的不可变类的能力,而更改的属性很少?
1条答案
按热度按时间46scxncf1#
我想没有比这更简单的方法了(lombok),但这不是java,所以。。。