Site icon imageTomoMemo.dev

Memo on programming. Provided by Tomo with passion.

Pythonで学ぶデザインパターン[Builder]

Icon in a callout block
Python 100Days Challenge Day18

ビルダーパターンについて学ぶ。

概要

  • オブジェクトを1つずつ構築するためのメソッドが含まれており、オブジェクトの準備が整ったら、特定のメソッドを実行して最終的にオブジェクトを作り出す
  • 将来的にオブジェクトが大きくなることが予想される場合に特に有用とされているコードの構成

問題

  • 多くのオブジェクトや入れ子状態のオブジェクトがあり、段階的な初期化が必要で複雑化したコードだと改修がしんどい
  • コンストラクタ(__init__メソッド)にたくさんの引数を渡さないといけないケース
    • どの引数がどの役割なのかが分かりにくい

基本構文

PythonでのBuilderパターンはこうなる。

例として、ケーキをつくるとき、スポンジ、クリーム、イチゴ、チョコレートなどたくさんの材料を使うことになる。これらを一度で全ての材料を使う、となるとパティシエは混乱するかもしれない。

そこで使うのがBuilderパターン。

書くコード

  • Cakeクラス
    • ケーキを表すクラス
    • スポンジ・クリーム・イチゴを属性として持つ
  • CakeBuilderクラス
    • ケーキを少しずつ組み立てるためのクラス
    • メソッド毎にケーキのパーツを追加していく
    • build()メソッドで完成したケーキを返す
  • ケーキを作るプロセス
    • CakeBuilderのインスタンスを作ってスポンジを追加、次にクリームを追加して最後にイチゴを追加してケーキを作る
class Cake:
    def __init__(self, sponge=None, cream=None, strawberry=None):
        self.sponge = sponge
        self.create = cream
        self.strawberry = strawberry
        
    def __str__(self): # オブジェクトの文字列表現を定義するために使う
        return f"Cake with {self.sponge}, {self.cream} and {self.strawberry}."

class CakeBuilder:
    def __init__(self):
        self.cake = cake()
        
    def add_sponge(self, sponge):
        self.cake.sponge = sponge
        return self
    
    def add_cream(self, cream):
        self.cake.cream = cream
        return self

    def add_strawberry(self, strawberry):
        self.cake.strawberry = strawberry
        return self

    def build(self):
        return self.cake

builder = CakeBuilder()
cake = (builder
        .add_sponge("vanilla sponge")
        .add_cream("chocolate cream")
        .add_strawberry("fresh strawberries")
        .build()

print(cake)

>      
Cake with vanilla sponge, chocolate cream and fresh strawberries.        

補足

__str__メソッドを使う目的は文字列の出力。デバッグやログを出力するときによく使う(らしい。)

Powered by Tomo with passion.