Der Builder implementiert Cloneable und überschreibt clone(). Anstatt jedes Feld des Builders zu kopieren, behält die unveränderliche Klasse einen privaten Clone des Builders bei. Dies macht es einfach, einen neuen Builder zurückzugeben und leicht modifizierte Kopien einer unveränderlichen Instanz zu erstellen.Ist dies eine gültige Java-Implementierung einer unveränderlichen Klasse und des Builder-Musters?
So kann ich
MyImmutable i1 = new MyImmutable.Builder().foo(1).bar(2).build();
MyImmutable i2 = i1.builder().foo(3).build();
Die klonbar Schnittstelle etwas gebrochen wird gesagt, gehen kann, werden aber nicht alle diese verletzen gute Java-Codierung Praxis gibt es irgendwelche Probleme mit diesem Konstrukt?
final class MyImmutable {
public int foo() { return builder.foo; }
public int bar() { return builder.bar; }
public Builder builder() { return builder.clone(); }
public static final class Builder implements Cloneable {
public Builder foo(int val) { foo = val; return this; }
public Builder bar(int val) { bar = val; return this; }
public MyImmutable build() { return new MyImmutable(this.clone()); }
private int foo = 0;
private int bar = 0;
@Override public Builder clone() { try { return (Builder)super.clone(); } catch(CloneNotSupportedException e) { throw new AssertionError(); } }
}
private MyImmutable(Builder builder) { this.builder = builder; }
private final Builder builder;
}
Ich habe versucht, einige Ecken zu schneiden und vermeiden, Felder explizit zu kopieren. Die "basedOn" -Methode ist wirklich klar, aber ich würde Felder (wieder) kopieren müssen. Vielleicht bin ich zu faul. – Aksel
Großartiger Vorschlag der basedOn Methode :) – troig