0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するBuilderパターン:段階的な生成で複雑なオブジェクトを構築する

Posted at

概要

Builder(ビルダー)パターンは、
複雑な構造を持つオブジェクトの生成処理を、段階的かつ分離された構造で提供するデザインパターンである。

生成処理を構成要素ごとに分け、読みやすく保守性の高いAPIで組み立てられるようにするのが目的。
オブジェクトの生成順序、依存性、初期状態をコード上に明示的に表現できる


1. なぜBuilderが必要か?

❌ コンストラクタで引数が増えすぎて可読性が低下

user = User("taro", 30, "tokyo", "engineer", "developer", True, False)

→ 引数の意味が不明、可読性とメンテナンス性に問題がある


✅ Builderを使って意図を明示しながら構築

user = (
    UserBuilder()
    .set_name("taro")
    .set_age(30)
    .set_location("tokyo")
    .set_job("engineer")
    .build()
)

各ステップで意味が明確な、流れるようなオブジェクト生成が可能に


2. 基本構造

✅ Product(構築対象のオブジェクト)

class User:
    def __init__(self, name="", age=0, location="", job=""):
        self.name = name
        self.age = age
        self.location = location
        self.job = job

    def __str__(self):
        return f"{self.name} ({self.age}) - {self.location} / {self.job}"

✅ Builderクラス

class UserBuilder:
    def __init__(self):
        self._user = User()

    def set_name(self, name):
        self._user.name = name
        return self

    def set_age(self, age):
        self._user.age = age
        return self

    def set_location(self, location):
        self._user.location = location
        return self

    def set_job(self, job):
        self._user.job = job
        return self

    def build(self):
        return self._user

✅ 使用例

user = (
    UserBuilder()
    .set_name("Hanako")
    .set_age(28)
    .set_location("Osaka")
    .set_job("Designer")
    .build()
)

print(user)

出力:

Hanako (28) - Osaka / Designer

3. Python的応用:辞書やJSON構造を段階的に組み立てる

class QueryBuilder:
    def __init__(self):
        self._query = {}

    def filter(self, key, value):
        self._query[key] = value
        return self

    def sort(self, field):
        self._query["sort"] = field
        return self

    def limit(self, n):
        self._query["limit"] = n
        return self

    def build(self):
        return self._query
query = QueryBuilder().filter("status", "active").limit(10).build()
print(query)

出力:

{'status': 'active', 'limit': 10}

4. 実務ユースケース

✅ 複雑なフォームデータの組み立て

途中でバリデーションや補完を加えつつ段階的に構築


✅ DSL的なクエリビルダー(SQL, GraphQL, MongoDB等)

構文木を段階的に積み上げて安全に組み立てる


✅ 大量設定を伴うUI部品の生成

スタイル・レイアウト・イベントを一貫した構文で設定可能


✅ テスト用のダミーデータファクトリ

→ 様々な属性を柔軟に組み合わせたオブジェクト生成が可能


5. よくある誤用と対策

❌ Builderで生成するオブジェクトの責務が曖昧

→ ✅ Builderは構築専用、ロジックはProductに持たせる


❌ ステップが固定されており順序変更できない

→ ✅ ステップは任意順・任意数で実行可能に設計する


❌ build() でバリデーションせずに不完全なオブジェクトを返す

→ ✅ 最終段階で一貫性チェックを挟む


結語

Builderパターンとは、“設計図をもとに、順を追って構造を組み立てる柔らかな生成技法”である。

  • 大量の属性や依存性を持つオブジェクトを、段階的かつ明示的に構築
  • 引数の羅列による曖昧さを避け、可読性・拡張性・保守性を向上
  • Pythonではメソッドチェーンやデフォルト引数を駆使し、洗練されたDSLのような生成コードを記述可能

Pythonicとは、“わかりやすく、流れるように意図を示す構造を持つこと”。
Builderパターンはその意図と構築の過程を、コードに優雅に刻む設計技法である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?