Builderパターンとは | GoFデザインパターン

記事内に広告が含まれています。

このページでは、GoFの23デザインパターンの一つであるBuilderパターンについて解説します。

Builderパターンは、複雑なオブジェクトの生成過程を分離し、同じ構築プロセスで異なる表現を生成できるデザインパターンです。

また、Java、C++、C#、VB.NETのサンプルコードを用いて、具体的な実装方法を示します。

これにより、プログラミングの理解が深まり、効率的なコードの書き方を学ぶことができます。

Builderパターンとは

Builderパターンは、複雑なオブジェクトの構築を容易にするために使用されます。

生成するオブジェクトが多くのステップやパラメータを持つ場合、Builderパターンを用いることで、オブジェクト生成を柔軟かつ整理された形で行うことが可能になります。

例えば、異なる種類のドキュメント、複雑なUIコンポーネント、または構造が異なる製品を作成する際に非常に有効です。

Builderパターンのメリット

Builderパターンを使用することで、以下のような利点があります:

  • オブジェクトの生成プロセスをカプセル化できるため、クライアントコードを簡潔に保つことができる。
  • 生成するオブジェクトのバリエーションを簡単に追加できる。
  • 複雑なオブジェクトを分割して生成するため、コードの再利用性が向上する。

Builderパターンの使い方

Builderパターンは、主に次の要素で構成されます。

1. Builderインターフェース

オブジェクトの生成手順を定義します。

このインターフェースは、オブジェクトの部分を段階的に生成するためのメソッドを提供します。

2. ConcreteBuilderクラス

Builderインターフェースを実装し、具体的な生成プロセスを提供します。

このクラスは、最終的な製品オブジェクトを保持し、必要なステップを通じてオブジェクトを構築します。

3. Directorクラス

Builderを利用してオブジェクトの生成を指示します。

具体的な手順や順序を決定し、Builderに依頼してオブジェクトを生成します。

4. Productクラス

最終的に生成されるオブジェクトを表します。Builderは、このProductオブジェクトを段階的に構築していきます。

Builderパターン実装サンプル

以下に、Java、C++、C#、VB.NETでのBuilderパターンの実装例を紹介します。

それぞれの言語で、オブジェクトの生成方法や構文の違いを理解することで、実際のプロジェクトに適した言語でBuilderパターンを活用できるようになります。

JavaによるBuilderパターン実装


// Builderインターフェース
public interface Builder {
    void setPartA();
    void setPartB();
    Product getResult();
}

// ConcreteBuilderクラス
public class ConcreteBuilder implements Builder {
    private Product product = new Product();

    @Override
    public void setPartA() {
        product.setPartA("Part A");
    }

    @Override
    public void setPartB() {
        product.setPartB("Part B");
    }

    @Override
    public Product getResult() {
        return product;
    }
}

// Directorクラス
public class Director {
    public void construct(Builder builder) {
        builder.setPartA();
        builder.setPartB();
    }
}

// Productクラス
public class Product {
    private String partA;
    private String partB;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }

    @Override
    public String toString() {
        return "Product [partA=" + partA + ", partB=" + partB + "]";
    }
}

// 使用例
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director();
        director.construct(builder);
        Product product = builder.getResult();
        System.out.println(product);
    }
}

C++によるBuilderパターン実装


#include 
#include 
using namespace std;

// Builderインターフェース
class Builder {
public:
    virtual void setPartA() = 0;
    virtual void setPartB() = 0;
    virtual string getResult() = 0;
};

// ConcreteBuilderクラス
class ConcreteBuilder : public Builder {
private:
    string partA;
    string partB;

public:
    void setPartA() override {
        partA = "Part A";
    }

    void setPartB() override {
        partB = "Part B";
    }

    string getResult() override {
        return "Product [partA=" + partA + ", partB=" + partB + "]";
    }
};

// Directorクラス
class Director {
public:
    void construct(Builder& builder) {
        builder.setPartA();
        builder.setPartB();
    }
};

// 使用例
int main() {
    ConcreteBuilder builder;
    Director director;
    director.construct(builder);
    cout << builder.getResult() << endl;
    return 0;
}

C#によるBuilderパターン実装


// Builderインターフェース
public interface IBuilder {
    void SetPartA();
    void SetPartB();
    Product GetResult();
}

// ConcreteBuilderクラス
public class ConcreteBuilder : IBuilder {
    private Product product = new Product();

    public void SetPartA() {
        product.PartA = "Part A";
    }

    public void SetPartB() {
        product.PartB = "Part B";
    }

    public Product GetResult() {
        return product;
    }
}

// Productクラス
public class Product {
    public string PartA { get; set; }
    public string PartB { get; set; }

    public override string ToString() {
        return $"Product [PartA={PartA}, PartB={PartB}]";
    }
}

// Directorクラス
public class Director {
    public void Construct(IBuilder builder) {
        builder.SetPartA();
        builder.SetPartB();
    }
}

// 使用例
class Program {
    static void Main(string[] args) {
        IBuilder builder = new ConcreteBuilder();
        Director director = new Director();
        director.Construct(builder);
        Product product = builder.GetResult();
        Console.WriteLine(product);
    }
}

VB.NETによるBuilderパターン実装


' Builderインターフェース
Public Interface IBuilder
    Sub SetPartA()
    Sub SetPartB()
    Function GetResult() As Product
End Interface

' ConcreteBuilderクラス
Public Class ConcreteBuilder
    Implements IBuilder

    Private product As New Product()

    Public Sub SetPartA() Implements IBuilder.SetPartA
        product.PartA = "Part A"
    End Sub

    Public Sub SetPartB() Implements IBuilder.SetPartB
        product.PartB = "Part B"
    End Sub

    Public Function GetResult() As Product Implements IBuilder.GetResult
        Return product
    End Function
End Class

' Productクラス
Public Class Product
    Public Property PartA As String
    Public Property PartB As String

    Public Overrides Function ToString() As String
        Return String.Format("Product [PartA={0}, PartB={1}]", PartA, PartB)
    End Function
End Class

' Directorクラス
Public Class Director
    Public Sub Construct(builder As IBuilder)
        builder.SetPartA()
        builder.SetPartB()
    End Sub
End Class

' 使用例
Module Module1
    Sub Main()
        Dim builder As New ConcreteBuilder()
        Dim director As New Director()
        director.Construct(builder)
        Dim product As Product = builder.GetResult()
        Console.WriteLine(product)
    End Sub
End Module

まとめ

Builderパターンは、複雑なオブジェクトの生成を効率化するためのデザインパターンです。

異なる要件を持つオブジェクトを同じ生成プロセスで作成することが可能であり、柔軟性が高まります。Java、C++、C#、VB.NETそれぞれでの実装サンプルを通じて、具体的な活用方法を理解することができました。

プロジェクトに応じて、最適なデザインパターンを選択し、効率的なコード設計を行いましょう。

オブジェクト指向プログラミングにおけるGoFの23のデザインパターン
デザインパターンは、ソフトウェア設計の問題を効果的に解決するための再利用可能な解決策です。本記事では、GoF(Gang ...
タイトルとURLをコピーしました