Im Jahr 2007 las ich einen Artikel über Joshua Blochs "Builder-Pattern" und wie es modifiziert werden könnte, um die Übernutzung von Konstruktoren und Setzern zu verbessern, insbesondere wenn ein Objekt eine große Anzahl von Eigenschaften hat, von denen die meisten optional sind. Eine kurze Zusammenfassung dieses Entwurfsmusters finden Sie hier .
Ich mochte die Idee und benutze sie seitdem. Das Problem dabei ist, dass es aus Kundensicht sehr sauber und schön zu bedienen ist. Die Implementierung kann jedoch nerven! Es gibt so viele verschiedene Stellen im Objekt, an denen eine einzelne Eigenschaft referenziert wird. Das Erstellen des Objekts und das Hinzufügen einer neuen Eigenschaft nimmt daher viel Zeit in Anspruch.
Also ... ich hatte eine Idee. Zunächst ein Beispielobjekt im Stil von Joshua Bloch:
Josh Bloch Style:
public class OptionsJoshBlochStyle {
private final String option1;
private final int option2;
// ...other options here <<<<
public String getOption1() {
return option1;
}
public int getOption2() {
return option2;
}
public static class Builder {
private String option1;
private int option2;
// other options here <<<<<
public Builder option1(String option1) {
this.option1 = option1;
return this;
}
public Builder option2(int option2) {
this.option2 = option2;
return this;
}
public OptionsJoshBlochStyle build() {
return new OptionsJoshBlochStyle(this);
}
}
private OptionsJoshBlochStyle(Builder builder) {
this.option1 = builder.option1;
this.option2 = builder.option2;
// other options here <<<<<<
}
public static void main(String[] args) {
OptionsJoshBlochStyle optionsVariation1 = new OptionsJoshBlochStyle.Builder().option1("firefox").option2(1).build();
OptionsJoshBlochStyle optionsVariation2 = new OptionsJoshBlochStyle.Builder().option1("chrome").option2(2).build();
}
}
Nun meine "verbesserte" Version:
public class Options {
// note that these are not final
private String option1;
private int option2;
// ...other options here
public String getOption1() {
return option1;
}
public int getOption2() {
return option2;
}
public static class Builder {
private final Options options = new Options();
public Builder option1(String option1) {
this.options.option1 = option1;
return this;
}
public Builder option2(int option2) {
this.options.option2 = option2;
return this;
}
public Options build() {
return options;
}
}
private Options() {
}
public static void main(String[] args) {
Options optionsVariation1 = new Options.Builder().option1("firefox").option2(1).build();
Options optionsVariation2 = new Options.Builder().option1("chrome").option2(2).build();
}
}
Wie Sie in meiner "verbesserten Version" sehen können, gibt es zwei Stellen weniger, an denen wir Code über zusätzliche Eigenschaften (oder Optionen in diesem Fall) hinzufügen müssen! Das einzige Negative, das ich sehen kann, ist, dass die Instanzvariablen der äußeren Klasse nicht endgültig sein können. Aber die Klasse ist ohne dies immer noch unveränderlich.
Gibt es wirklich Nachteile bei dieser Verbesserung der Wartbarkeit? Muss es einen Grund geben, warum er die Eigenschaften innerhalb der verschachtelten Klasse wiederholt, die ich nicht sehe?