Index
書籍では以下のように説明されていました。
構造を持ったインスタンスを組み上げていくものを
Builderパターンと呼ぶ
- 組み上げていく過程の詳細を隠蔽できる
- 交換可能性を持つことができる
- 依存性の注入(DI)をすることができる
詳細はサンプルコードを見ながら解説していきます。
文章を作るインターフェースです。
抽象クラスとして定義してもOKです。
1 2 3 4 5 6 |
public interface Builder { public abstract void makeTitle(final String title); public abstract void makeString(final String str); public abstract void makeItems(final String[] items); public abstract void close(); } |
Builderクラスに宣言されているメソッドを使って、construct()メソッド内で文章を組み上げていきます。
このクラスでは先述したメリット①〜③を確認することができます。
まずconstruct()メソッド内で「組み上げていく過程を隠蔽している」ことを確認できます。(メリット①)
次にコンストラクタの引数がインターフェースであることに注目してください。
これによりBuilderクラスを実装したクラスであればどんなクラスでも引数として渡してあげることができます。(メリット②③)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Director { private final Builder m_builder; public Director(final Builder builder) { m_builder = builder; } public void construct() { m_builder.makeTitle("私の好きな果物"); m_builder.makeString("ランキング"); m_builder.makeItems(new String[] { "リンゴ", "みかん", "もも", }); m_builder.close(); } } |
実際にどのような文章を作るかを実装しているクラスです。
なぜString型ではなく、StringBuilder型の変数を持っているかというと、文字列を連結する際の実行効率が良いからです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
public class TextBuilder implements Builder{ private StringBuilder m_builder = new StringBuilder(); @Override public void makeTitle(final String title) { m_builder.append("**************¥n"); m_builder.append("----"); m_builder.append(title); m_builder.append("----¥r¥r"); } @Override public void makeString(final String str) { m_builder.append(""); m_builder.append(str); m_builder.append("¥n¥n"); } @Override public void makeItems(final String[] items) { for(final String item : items) { m_builder.append("+"); m_builder.append(item); m_builder.append("¥n"); } } @Override public void close() { m_builder.append("**************"); } public String getText() { return m_builder.toString(); } } |
1 2 3 4 5 6 7 8 |
public class Main { public static void main(String[] args) { final TextBuilder textBuilder = new TextBuilder(); final Director director = new Director(textBuilder); director.construct(); System.out.println(textBuilder.getText()); } } |
出力は以下の通りです。
1 2 3 4 5 6 7 8 9 |
************** ----私の好きな果物---- □ランキング +リンゴ +みかん +もも ************** |