動機
最近、コンストラクターに多くのパラメーターを渡さずに複雑なオブジェクトを初期化する方法を探しました。ビルダーパターンで試してみましたが、本当に必要な値をすべて設定したかどうかをコンパイル時に確認できないのが気になりません。
従来のビルダーパターン
ビルダーパターンを使用してComplex
オブジェクトを作成すると、引数が何に使用されているかを確認しやすくなるため、作成はより「タイプセーフ」になります。
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
...
.build();
しかし今、私は問題を抱えています。それは、重要なパラメータを簡単に見逃してしまう可能性があるということです。build()
メソッド内で確認できますが、それは実行時のみです。コンパイル時に、何かを見逃した場合に警告するものは何もありません。
強化されたビルダーパターン
今の私のアイデアは、必要なパラメーターを見逃した場合に「思い出させる」ビルダーを作成することでした。私の最初の試みは次のようになります:
public class Complex {
private String m_first;
private String m_second;
private String m_third;
private Complex() {}
public static class ComplexBuilder {
private Complex m_complex;
public ComplexBuilder() {
m_complex = new Complex();
}
public Builder2 setFirst( String first ) {
m_complex.m_first = first;
return new Builder2();
}
public class Builder2 {
private Builder2() {}
Builder3 setSecond( String second ) {
m_complex.m_second = second;
return new Builder3();
}
}
public class Builder3 {
private Builder3() {}
Builder4 setThird( String third ) {
m_complex.m_third = third;
return new Builder4();
}
}
public class Builder4 {
private Builder4() {}
Complex build() {
return m_complex;
}
}
}
}
ご覧のとおり、ビルダークラスの各セッターは異なる内部ビルダークラスを返します。各内部ビルダークラスは正確に1つのsetterメソッドを提供し、最後のクラスはbuild()メソッドのみを提供します。
これで、オブジェクトの構築は次のようになります。
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
.build();
...しかし、必要なパラメータを忘れる方法はありません。コンパイラはそれを受け入れません。
オプションのパラメータ
オプションのパラメーターがある場合は、最後の内部ビルダークラスを使用してBuilder4
、「従来の」ビルダーと同じようにパラメーターを設定し、それ自体を返します。
質問
- これはよく知られているパターンですか?特別な名前はありますか?
- 落とし穴はありますか?
- コードの行数を減らすという意味で、実装を改善するためのアイデアはありますか?