TechCraft – エンジニアのためのスキルアップメモ

エンジニアのスキルアップを少しでも加速する技術ブログ

デザインパターン第2回 Factory & Builder

GoFGang of Four)のデザインパターン:Factory & Builderパターンを徹底解説

1. はじめに

ソフトウェア開発において、「オブジェクトの作成をどのように管理するか?」 は重要な課題です。
適切な方法を選ばなければ、コードが煩雑になり、再利用性や拡張性が損なわれる 可能性があります。

この問題を解決するために、GoFGang of Four)が提唱したデザインパターンの中でも、「Factoryパターン」と「Builderパターン」 は、
オブジェクトの生成を柔軟かつ分かりやすくする方法として広く採用されています。

本記事では、FactoryパターンとBuilderパターンの概要、利点、実装方法(複数言語での実装) を詳しく解説します。


2. Factoryパターン:オブジェクト生成の委譲

2.1. Factoryパターンとは?

Factoryパターン(工場パターン) は、オブジェクトの生成を「Factory(工場)」に委ねることで、コードの柔軟性を向上させる デザインパターンです。

メリット - クライアント側で new を直接使用しないため、依存関係が減る - 生成ロジックを1箇所にまとめることで、拡張しやすい設計になる - インターフェースを統一できるため、異なる種類のオブジェクトを扱いやすい

デメリット - クラス数が増え、コードが複雑になる - 単純なオブジェクト生成では不要な場合もある


2.2. 各言語でのFactoryパターンの実装

Javaでの実装

// 製品のインターフェース
interface Product {
    void use();
}

// 具体的な製品A
class ProductA implements Product {
    public void use() {
        System.out.println("Product A を使用中");
    }
}

// 具体的な製品B
class ProductB implements Product {
    public void use() {
        System.out.println("Product B を使用中");
    }
}

// Factory(オブジェクト生成を担うクラス)
class ProductFactory {
    public static Product createProduct(String type) {
        if (type.equals("A")) {
            return new ProductA();
        } else if (type.equals("B")) {
            return new ProductB();
        } else {
            throw new IllegalArgumentException("未知の製品タイプ");
        }
    }
}

// 使用例
public class Main {
    public static void main(String[] args) {
        Product product = ProductFactory.createProduct("A");
        product.use();  // Output: Product A を使用中
    }
}

ProductFactory がオブジェクト生成を管理し、クライアント側は単純なAPIでアクセス可能


Pythonでの実装

class Product:
    def use(self):
        pass

class ProductA(Product):
    def use(self):
        print("Product A を使用中")

class ProductB(Product):
    def use(self):
        print("Product B を使用中")

class ProductFactory:
    @staticmethod
    def create_product(product_type):
        if product_type == "A":
            return ProductA()
        elif product_type == "B":
            return ProductB()
        else:
            raise ValueError("未知の製品タイプ")

# 使用例
product = ProductFactory.create_product("B")
product.use()  # Output: Product B を使用中

Pythonでも同様に ProductFactory がオブジェクト生成を管理する


3. Builderパターン:複雑なオブジェクトの構築

3.1. Builderパターンとは?

Builderパターン(ビルダーパターン) は、
「複雑なオブジェクトの生成過程を、手順ごとに分割して管理する」デザインパターン です。

メリット - 手順を分けて管理できる ため、複雑なオブジェクトの生成が容易 - オブジェクトの不変性(Immutable)を維持 しやすい - オプションのパラメータを柔軟に設定可能

デメリット - 設計がやや複雑 になる - 単純なオブジェクトには不向き


3.2. 各言語でのBuilderパターンの実装

Javaでの実装

class Product {
    private String partA;
    private String partB;

    private Product(Builder builder) {
        this.partA = builder.partA;
        this.partB = builder.partB;
    }

    public static class Builder {
        private String partA;
        private String partB;

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

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

        public Product build() {
            return new Product(this);
        }
    }

    public void show() {
        System.out.println("Product with " + partA + " and " + partB);
    }
}

// 使用例
public class Main {
    public static void main(String[] args) {
        Product product = new Product.Builder()
            .setPartA("A")
            .setPartB("B")
            .build();

        product.show();  // Output: Product with A and B
    }
}

Builderパターンを使うことで、オブジェクトの作成を簡潔に管理できる


Pythonでの実装

class Product:
    def __init__(self, part_a=None, part_b=None):
        self.part_a = part_a
        self.part_b = part_b

    def show(self):
        print(f"Product with {self.part_a} and {self.part_b}")

class ProductBuilder:
    def __init__(self):
        self.product = Product()

    def set_part_a(self, part_a):
        self.product.part_a = part_a
        return self

    def set_part_b(self, part_b):
        self.product.part_b = part_b
        return self

    def build(self):
        return self.product

# 使用例
builder = ProductBuilder()
product = builder.set_part_a("A").set_part_b("B").build()
product.show()  # Output: Product with A and B

PythonのBuilderパターンも同様に、メソッドチェーンでオブジェクトを構築可能


4. まとめ

項目 内容
Factoryパターンとは? オブジェクトの生成を「Factory」に委ねることで、コードの柔軟性を向上
Factoryのメリット 依存関係の低減、オブジェクトの生成ロジックを一元管理
Builderパターンとは? 複雑なオブジェクトの生成過程を分離し、メソッドチェーンで管理
Builderのメリット 不変性の維持、オプションパラメータの管理が容易

Factoryパターンは「種類ごとのオブジェクトを簡単に生成」 し、
Builderパターンは「複雑なオブジェクトを段階的に構築」 するために有効です。

📌 次回の記事:「GoFの構造パターン(Adapter, Decorator, Facade)」もお楽しみに!

参考資料

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Java言語で学ぶデザインパターン入門第3版 [ 結城 浩 ]
価格:4,290円(税込、送料無料) (2025/3/7時点)


バランスよく書かれている。


網羅的に書かれています。骨太。


C++デザインパターン。少し高難度。