Python Builder パターンを実装するさまざまな方法
Builder パターンは、オブジェクトの作成をその表現から切り離すことを可能にするパターンです。 このパターンは、継承なしで複雑なオブジェクトを作成および構成できます。これは強力ですが、柔軟性に欠けるアプローチです。
ビルダー パターンを利用して、実行時にクラスのさまざまな実装を提供したり、ユーザーがソース コードにアクセスせずに新しいオブジェクトを構築できるようにしたりすることもできます。
このチュートリアルでは、ビルダー パターンとその仕組みについて説明します。 また、Python ビルダー パターンを実装するさまざまな方法も示します。
Builder パターン、その重要性と機能
ビルダー パターンは、複雑なオブジェクトの構築を段階的に作成できるようにするソフトウェア設計パターンであり、新しいレベルの詳細または機能を提供します。
このパターンは、さまざまなソフトウェア コンポーネントを組み合わせて完全なシステムを形成する必要があるソフトウェア開発でよく使用されます。
ビルダー パターンは、テーブルや椅子などの単純なオブジェクトから、コンピューターや飛行機などのより複雑なシステムまで、あらゆるものを作成するために利用できます。 また、特定の順序で作成する必要があるオブジェクトを作成する場合にも役立ちます。
Python 標準ライブラリには builder
というモジュールが用意されており、Builder パターンを簡単に使用できます。 ビルダー モジュールは、連携してオブジェクトを作成する Builder
と Director
の 2つのクラスを提供します。
Builder
クラスはオブジェクト パーツの作成を担当し、Director
クラスはコンポーネントを最終的なオブジェクトに組み立てるために使用されます。
Builder
パターンを使用するには、最初に Builder
オブジェクトを作成します。これを使用して、オブジェクトのパーツを作成します。 それから Director
オブジェクトを作成し、これを使用してピースを最終的なオブジェクトに組み立てます。
最後に、最終的なオブジェクトを返す Director
オブジェクトで build()
メソッドを呼び出すことができます。
Python で Builder パターンを実装するさまざまな方法
Python で Builder パターンを実装するには、次の 2つの方法があります。
__init__
メソッド__new__
メソッド
__init__
メソッドを使用する
__init__
メソッドは、Python で Builder
パターンを実装する最も一般的な方法です。 オブジェクトの作成時に呼び出され、その属性の値を設定できます。
__new__
メソッドを使用する
__new__
メソッドはあまり一般的ではありませんが、より強力です。 クラスの作成時に __new__
メソッドが呼び出され、オブジェクト自体を作成できるようになります。
これは、オブジェクトの作成方法を制御でき、クラスと同じ型ではないオブジェクトを作成できることを意味します。
Python での Builder パターンの長所と短所
ビルダー パターンには、以下に示すいくつかの利点があります。
- ビルダー パターンの本質的な利点は、複雑なオブジェクトを段階的に作成し、新しいレベルの詳細または機能を提供できることです。
- これにより、複雑なオブジェクトをより簡単かつ効率的に作成できます。
- ビルダーパターンは、さまざまなビルダーがさまざまなタイプのオブジェクトを作成できるため、高度な柔軟性を可能にするという利点もあります。
ビルダー パターンの使用にもいくつかの欠点があります。
- 1つは、各ステップを順番に実行する必要があるため、オブジェクトの作成に非常に時間がかかることです。
- もう 1つの欠点は、ビルダー パターンが非常に複雑になり、多くのコードを記述する必要があることです。
コード例:
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Any
class Builder(ABC):
@property
@abstractmethod
def product(self) -> None:
pass
@abstractmethod
def produce_a(self) -> None:
pass
"""
This class will provide specific working of the building steps by using the builder interface.
"""
class ConcreteBuilder1(Builder):
def __init__(self) -> None:
"""This fresh builder instance will contain a blank product object, which is
used in further assembly.
"""
self.reset()
def reset(self) -> None:
self._product = Product1()
@property
def product(self) -> Product1:
product = self._product
self.reset()
return product
def produce_a(self) -> None:
self._product.add("PartA")
class Product1:
"""
When your products are complex and demand extensive configuration, it's possible to use the Builder pattern only.
"""
def __init__(self) -> None:
self.parts = []
def add(self, part: Any) -> None:
self.parts.append(part)
def list_parts(self) -> None:
print(f"The Product parts: {', '.join(self.parts)}", end="")
class Director:
"""
The client can control builders directly, so the Director class is
optional. In this case, the Director is only responsible for executing the building steps in a specific sequence.
"""
def __init__(self) -> None:
self._builder = None
@property
def builder(self) -> Builder:
return self._builder
"""
The Director can construct several product variations using the same
building steps.
"""
@builder.setter
def builder(self, builder: Builder) -> None:
self._builder = builder
def build_minimal_viable_product(self) -> None:
self.builder.produce_a()
def build_full_featured_product(self) -> None:
self.builder.produce_a()
if __name__ == "__main__":
director = Director()
builder = ConcreteBuilder1()
director.builder = builder
print("Our Standard primary product:")
director.build_minimal_viable_product()
builder.product.list_parts()
print("\n")
print("Our Standard full-featured product:")
director.build_full_featured_product()
builder.product.list_parts()
print("\n")
# We can also use the Builder pattern without a Director class.
print("Our Custom product: ")
builder.produce_a()
builder.product.list_parts()
出力:
Our Standard primary product:
The Product parts: PartA
Our Standard full-featured product:
The Product parts: PartA
Our Custom product:
The Product parts: PartA
Builder パターンは、構造と表現を分離することによって複雑なオブジェクトを構築するのに役立つ設計パターンでもあることに注意してください。 この分離により、同じ構築プロセスから異なる表現を作成できます。
Zeeshan is a detail oriented software engineer that helps companies and individuals make their lives and easier with software solutions.
LinkedIn