パンくず
Effective Java
数多くのコンストラクタパラメータに直面した時にはビルダーを検討する
概要
数多くのコンストラクタパラメータに直面した時にはビルダーを検討する
想定されるケース
必須項目、オプション項目を含む多数の項目を扱うクラスを作成する場合
初期化の処理が煩雑になる。
解法1 テレスコーピングコンストラクタ
全項目指定した場合のコンストラクタを用意し、オプションを省略する場合のコンストラクタは
オプション項目だけ初期値を設定した上で全項目用のコンストラクタをチェーンして呼び出す。
オプション項目が増えれば増えるほどコンストラクタの数が増えることや、
予備元が値を指定する場合に、「引数のN番目はこの項目」という情報を覚える必要があり
利用や保守が困難。
テレスコーピングコンストラクタ・パターン サンプルコード
public class Hoge private final String hoge;// 必須 private final String hige;// オプション private final String hage;// オプション public Hoge(String hoge,String hige,String hage) { this.hoge = hoge; this.hige = hige; this.hage = hage; } public Hoge(String hoge,String hige) { Hoge(hoge,hige,"初期値"); } public Hoge(String hoge) { Hoge(hoge,"初期値","初期値"); }
解法3 ビルダーを利用したパターン
生成手順をビルダーにまとめます。
この際に、各メンバーの名称そのままのメソッドから値を設定することで
どの項目を設定しているのかわかりやすくします。
さらにビルダーのインスタンスを返却し、流れるようなインターフェースを実装することで
可読性を高めます。
ビルダーを利用したパターンのサンプルコード
package effective.creation.chapter2; public class Hoge { public static class HogeBuilder { // 必須 private String hoge = ""; // オプション private String hige = "初期値"; private String hage = "初期値"; public HogeBuilder(String hoge) { this.hoge = hoge; } public Hoge build() { return new Hoge(this); } public HogeBuilder hage(String hage) { this.hage = hage; return this; } public HogeBuilder hige(String hige) { this.hige = hige; return this; } public HogeBuilder hoge(String hoge) { this.hoge = hoge; return this; } } private String hoge = ""; private String hige = ""; private String hage = ""; private Hoge(HogeBuilder hogeBuilder) { this.hoge = hogeBuilder.hoge; this.hige = hogeBuilder.hige; this.hage = hogeBuilder.hage; } @Override public String toString() { return "hoge:" + hoge + "\nhige:" + hige + "\nhage:" + hage + "\n"; } }
呼び出しコード
package effective.creation.chapter2; public class HogeUser { public static void main(String[] args) { Hoge hogeAll = new Hoge.HogeBuilder("hoge").hige("hige").hage("hage").build(); System.out.println(hogeAll); Hoge hogeHige = new Hoge.HogeBuilder("hoge").hige("hige").build(); System.out.println(hogeHige); Hoge hogeHage = new Hoge.HogeBuilder("hoge").hage("hage").build(); System.out.println(hogeHage); } }
出力
hoge:hoge hige:hige hage:hage hoge:hoge hige:hige hage:初期値 hoge:hoge hige:初期値 hage:hage