デザインパターン学習メモ:「Builder」


目的

複合オブジェクトについて、その作成過程を表現形式に依存しないものにすることにより、同じ作成過程で異なる表現形式のオブジェクトを生成できるようにする(GoF本、P.105)

実装例

Main.java
public class Main {

    public static void main(String[] args) {
        Director director = new Director(new MarkdownBuilder());
        String text = director.construct();
        System.out.println(text);
    }
}
Director
public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public String construct() {
        builder.makeHeadline("headline 1");
        builder.makeStrongText("strong text");
        return builder.getResult();
    }
}
Builder.java
public interface Builder {
    void makeHeadline(String text);
    void makeStrongText(String text);
    String getResult();
}
MarkdownBuilder.java
public class MarkdownBuilder implements Builder {
    private StringBuffer buffer = new StringBuffer();

    @Override
    public void makeHeadline(String text) {
        buffer.append("# text");
        buffer.append("\n");
    }

    @Override
    public void makeStrongText(String text) {
        buffer.append("**");
        buffer.append(text);
        buffer.append("**");
    }

    @Override
    public String getResult() {
        return buffer.toString();
    }
}

実装例の解説

  • MainクラスはDirectorを生成する。DirectorはフィールドにBuilderの具象クラスを持つ
  • Directorのconstructメソッドを呼ぶと、Builder内に目的のオブジェクトが作られる
    • constructメソッドは、Buidlerがもつオブジェクト生成用メソッドを1つ以上呼び出す
  • 最後に、Builder内の完成したオブジェクトをgetResult()で取得する

ポイント

  • Directorがフィールドとして持つBuilderの具象クラスを切り替えることで、生成されるオブジェクトの表現形式を変えることができる
    • 実装例だと、MarkdownのテキストやHTMLのテキストを切り替える
  • 新しいDirectorを実装することで、すでにあるBuidlerをつかって、異なるプロセスでproduct(Builderによって生成されるオブジェクト)を生成できる
  • productの 内部表現や内部構造が、Builderによって隠蔽される
    • つまり、Builderだけが知っている
  • オブジェクトの生成プロセスは、Director内に局所化される

使いどころ

GoF本にでてきた例の1つがわかりやすかったので、引用する。

コンパイラサブシステム内のParserクラスは、(中略)Directorクラスである。Parserオブジェクトは、文法上の構文を認識するたびに、ProgramNodeBuilderオブジェクトに通知を送る。構文解析が終了するときに、Parserオブジェクトは、ProgramNodeBuilderオブジェクトに対して、それまでに作成した構文解析木を要求し、それをクライアントに返す。(P.114)

DirectorクラスとしてのParserが、構文解析を行いながら、Buidlerにオブジェクト(解析木)生成のためのメッセージを送る。Builder内に解析木が出来上がっていき、完成したらそれを取り出すのである。

参考文献

  • エリック ガンマ、ラルフ ジョンソン、リチャード ヘルム、ジョン プリシディース(1999)『オブジェクト指向における再利用のためのデザインパターン 改訂版』本位田 真一、吉田 和樹 監訳、SBクリエイティブ
  • 結城浩(2004)『Java言語で学ぶ デザインパターン入門』SBクリエイティブ