2007年に、Joshua Blochsが「ビルダーパターン」を採用し、コンストラクターとセッターの過剰使用を改善するためにどのように変更できるかについての記事を読みました。このデザインパターンの簡単な概要は、こちらで説明されています。
私はこのアイデアが好きで、それ以来ずっと使っています。それに伴う問題は、クライアントの観点からは非常にクリーンで使いやすいものですが、それを実装するのは苦痛になる可能性があります!オブジェクトには単一のプロパティが参照される非常に多くの異なる場所があるため、オブジェクトを作成し、新しいプロパティを追加するには時間がかかります。
だから...私は考えていました。まず、Joshua Blochスタイルのオブジェクトの例:
ジョシュブロッホスタイル:
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();
}
}
今、私の「改善された」バージョン:
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();
}
}
「改良版」でわかるように、追加のプロパティ(またはこの場合はオプション)に関するコードを追加する必要がある場所が2つ少なくなっています!私が見ることができる唯一のマイナスは、外側のクラスのインスタンス変数がfinalになれないことです。しかし、クラスはこれがなければ不変です。
この保守性の改善には、本当にマイナス面はありますか?私が見ないネストされたクラス内でプロパティを繰り返した理由がなければなりませんか?