2010年5月16日日曜日

Builderパターン

Builderパターンとは、文字通りビルド(組み立て、建築、構築)のためのパターンです。このパターンに出てくる人物は実際に建物を作る時と同様に、建築者、監督者、依頼人です。要件によって作るものは異なりますから、実際には上記に加えて、要件に特化した建築者もいます(本では具体的建築者なんて言っていますが)


まず、建築者はインスタンスを作るためのインターフェースを決めます。Builderクラスは以下のような感じです。
public abstract class Builder {
    public abstract void makeEntrance();
    public abstract void makeRoom(String name);
    ・・・
}

上のクラスを継承したクラス(ようは要件に特化した建築者)は以下のようにします。他の要件の場合でも同様に継承して作ればよいでしょう。
public class ABCBuilder extends Builder {
    public void makeEntrance() {
        ・・・
    }

    public void makeRoom(String name) {
        ・・・
    }
}

監督者であるDirectorクラスは、Builderクラスで宣言されているメソッドを使用して、実際に建築の指示をします。
public class Director {
    private Builder builder;
    public Director (Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.makeEntrance();
        builder.makeRoom("staff room");
        ・・・
    }
}
コンストラクタの引数がBuilderクラスのオブジェクトになっています。ここに、特化した建築者を入れてあげます。ソースを見てのとおり、監督者はBuilderクラスのメソッドしか呼ばないため、具体的にどんな建築者がやってきたのかを監督者であるDirectorは知りません。ですが、監督者は別にそんなことを意識しなくても必要な操作、つまり、Builderクラスで定義したメソッドを呼ぶことができちゃいます。

Mainクラスでは、要件に応じてABCBuilderクラスのインスタンス又はDEFBuilderクラスのインスタンスを生成し、Directorに構築の依頼をします。
public static void main(String[] args) {
    ・・・
    Director director = null;
    if ("ABC".equals(args[0])) {
        ABCBuilder abc = new ABCBuilder();
        director = new Director(abc);
    } else {
        DEFBuilder def = new DEFBuilder();
        director = new Director(def);
    }
    director.construct();
    ・・・
}

ここでのポイントは、依頼者であるMainクラスは、ABCとDEFがどのように構築されるかは知りません。ただ単に監督者に構築をお願いしただけです。そして、先程も説明しましたが、監督者はどんな建築者がやってこようと必要な指示をするだけで済んでいます。このパターンは各クラス間の独立性が高いことと、拡張性がある(別の用件に特化した建築者を作っても容易に対応出来る)のが特徴です。ですが、(他のパターンでも言えることですが)クラスの役割はしっかり理解しましょう。DirectorがABCBuilderのメソッドを呼ぶなんて以ての外です。

関連パターン
TemplateMethodパターン」今回のパターンでは、「DirectorがBuilderをコントロールする」パターンだったが、Template Methodパターンでは、「スーパークラスがサブクラスをコントロールする」パターン
Compositeパターン」作るものがCompositeになる場合がある。
Abstract Factoryパターン」どちらも複雑なインスタンスを生成するためのパターン
Facadeパターン」Facadeパターンは複数の処理をまとめて一つのメソッド(窓口)として実装し、外部からそのメソッドを呼ぶだけでよいパターン。BuilderパターンもBuilderが行う複数の処理をDirectorがまとめているという点で似ている。

0 件のコメント:

コメントを投稿