Dyuichi Blog

オブジェクト指向シリーズⅣ: デザインパターン [⑦ Builder]

概要

builderは日本語で「造り手」という意味になる.Builderパターンは,同じオブジェクトの作成過程で異なる表現形式のオブジェクトを得るためのパターンである.つまり,オブジェクトの作成とその表現を分離させることが目的である.

コンストラクタのパラメータが多い場合や,オブジェクトを構築する際に部品を異なる順番で構築したい場合に有効である.

Builderパターンの主な要素は以下である.

  • Builder:Productオブジェクトの各構成要素を生成するメソッドを定義したインターフェース
  • ConcreteBuilder:Builderインターフェースを実装したクラス
  • Director:Builderインターフェースを用いてオブジェクトを生成するクラス
  • Product:最終的に構築するオブジェクト

クラス図

画像が読み込まれない場合はページを更新してみてください。

実装例(Java)

java// Product
class Product {
    private String partA;
    private String partB;
    private String partC;

    public void setPartA(String partA) {
        this.partA = partA;
    }
    public void setPartB(String partB) {
        this.partB = partB;
    }
    public void setPartC(String partC) {
        this.partC = partC;
    }
    public void show() {
        System.out.println("Product: " + partA + " " + partB + " " + partC);
    }
}

// Builder
interface Builder {
    void buildPartA();
    void buildPartB();
    void buildPartC();
    Product getResult();
}

// ConcreteBuilder
class ConcreteBuilderX implements Builder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("partA-X");
    }
    @Override
    public void buildPartB() {
        product.setPartB("partB-X");
    }
    @Override
    public void buildPartC() {
        product.setPartC("partC-X");
    }
    @Override
    public Product getResult() {
        return product;
    }
}

class ConcreteBuilderY implements Builder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("partA-Y");
    }
    @Override
    public void buildPartB() {
        product.setPartB("partB-Y");
    }
    @Override
    public void buildPartC() {
        product.setPartC("partC-Y");
    }
    @Override
    public Product getResult() {
        return product;
    }
}

// Director
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

// Client
public class BuilderPattern {
    public static void main(String[] args) {
        Director directorX = new Director(new ConcreteBuilderX());
        Director directorY = new Director(new ConcreteBuilderY());

        Product productX = directorX.construct();
        Product productY = directorY.construct();

        productX.show();
        productY.show();
    }
}

まとめ,所感

最初はTemplate Method臭を若干感じたが,インスタンス化する際の処理が複雑な場合は,Builderパターンを用いることでクライアントからはかなり隠蔽できているように思う.