Builder
- 同じ生成手順で異なる材料を使って異なるオブジェクトを生成するパターン
- 「建築者」が利用者に渡された材料を使って、一連の手順に沿ってオブジェクトを生成する
- 家を建てるのと同じ
- 枠組みを作って、ドアをつけて、屋根をつけて、窓をつける…
- これらの手順は複数の家で同じものの材料が異なる
- 家を建てるのと同じ
- 「建築者」が利用者に渡された材料を使って、一連の手順に沿ってオブジェクトを生成する
- 「継承」「ポリモーフィズム」「移譲」を利用したパターン
BuilderとConcreteBuilderが継承(実装)関係DirectorはBuilderのAPIを使って様々なConcreteBuilderを操作することができるDirectorはBuilderのメソッドを呼び出して処理を移譲する
メリット・デメリット
メリット
- 生成されるオブジェクトの生成過程や生成手段を隠すことができる
- オブジェクト構築用のコードをビジネスロジックから分離することができる
デメリット
- 複数のクラスを作成する必要があり、過剰な設計となる可能性がある
用途
- 生成手順が同じで、詳細が異なるオブジェクトを生成する場合
- 大量のパラメータをコンストラクタに渡してオブジェクトを生成している場合
Builderの各工程で必要な値のみを渡すことで、パラメータを小分けにして渡すことができる- 可読性の向上とバグの可能性を低減させる
デザインパターンの種類
生成に関するデザインパターン
例(Mermaid)
Builder- インターフェースもしくは抽象クラス
- オブジェクトの「生成手段」となる
APIを提供する
ConcreteBuilderBuilderで提供されるAPIを実装するクラス- 生成したオブジェクトを取得するためのメソッドも提供する
Director- 「建築者」の役割を持つクラス
Builderクラスで定義されたAPIを使ってオブジェクトを生成する
classDiagram class Client{ } class Director{ builder construct() } class Builder{ <<interface>> buildPart1() buildPart2() buildPart3() } class ConcreteBuilder{ buildPart1() buildPart2() buildPart3() getResult() } class Product{ } Client --> Director Client --> ConcreteBuilder Director o--> Builder ConcreteBuilder ..|> Builder ConcreteBuilder --> Product
構成要素
sequenceDiagram participant Client participant Director participant ConcreteBuilder Client ->> ConcreteBuilder: new Client ->> +Director: construct Director ->> +ConcreteBuilder: buildPart1 ConcreteBuilder -->> -Director: Director ->> +ConcreteBuilder: buildPart2 ConcreteBuilder -->> -Director: Director ->> +ConcreteBuilder: buildPart3 ConcreteBuilder -->> -Director: Director ->> -Client: Client ->> ConcreteBuilder: getResult
classDiagram DesktopBuilder <-- Client LaptopBuilder <-- Client Computer <-- DesktopBuilder Computer <-- LaptopBuilder ComputerBuilder <.. DesktopBuilder :implements ComputerBuilder <.. LaptopBuilder :implements class Computer { type: string cpu: string ram: number } class ComputerBuilder { <<interface>> -computer Computer addCpu(cpu) addRam(ram) } class DesktopBuilder { -computer Computer addCpu(cpu) addRam(ram) getResult() Computer } class LaptopBuilder { -computer Computer addCpu(cpu) addRam(ram) getResult() Computer } class Client { } class Director{ builder ComputerBuilder construct() highSpecConstruct() } Client --> Director Director o--> ComputerBuilder