Builderパターン

Buliderクラスについてサンプルを書きます。
effective javaに書いているようなBuilderとGoFのBuilderは違うのかな?その辺がよくわかりませんが、GoFの方を書いていきます。目的は一緒だと思います。
effective javaのBuilderは下をご覧ください。

Bulderパターンですが生成に関するパターンで複合構造の構築に良く使われます。
監督者が(director)、指示を出して建築者 (Builder) が構築していくイメージです。

メリット
複雑なオブジェクトの構築方法をカプセル化できること

デメリット
構築がめんどくさ(ry

他にも複数の手順の変化するプロセスで柔軟なオブジェクトを作成できる点(Factoryとは対照的)がメリットとして挙げられますね。思っていたのと違うパラメータを設定している可能性もあるので一長一短ですが。

それでは作っていきます。夕飯を作ります。

パターン1:ステーキ定食(ご飯、ステーキ、オニオンスープ、ポテトサラダ)
パターン2:パン、ハンバーグ、シーザーサラダ

・Builder.php

<?php
interface Builder
{
    public function stapleFood(string $stapleFood):void;
    public function mainDish(string $mainDish):void;
    public function soup(string $soup):void;
    public function salad(string $salad):void;
    public function getResult();
}

・DinnerBuilder.php

<?php
require_once 'Builder.php';

class DinnerBuilder implements Builder
{
    private string $stapleFood;
    private string $mainDish;
    private string $soup;
    private string $salad;

    public function stapleFood(string $stapleFood): void
    {
        $this->stapleFood = $stapleFood;
    }

    public function mainDish(string $mainDish): void
    {
        $this->mainDish = $mainDish;
    }

    public function soup(string $soup): void
    {
        $this->soup = $soup;
    }

    public function salad(string $salad): void
    {
        $this->salad = $salad;
    }

    public function getResult(): dinnerBuilder
    {
        return $this;
    }
}

・Director.php

<?php

require_once 'Builder.php';

class Director
{

    private Builder $builder;

    public function __construct(Builder $builder){
        $this->builder = $builder;
    }

    public function makeSteakSetMeal(): void
    {
        $this->builder->stapleFood("rice");
        $this->builder->mainDish("steak");
        $this->builder->soup("onion soup");
        $this->builder->salad("potato salad");
    }

    public function addStapleFood(string $stapleFood): void
    {
        $this->builder->stapleFood($stapleFood);
    }

    public function addMainDish(string $mainDish): void
    {
        $this->builder->mainDish($mainDish);
    }

    public function addSoup(string $soup): void
    {
        $this->builder->soup($soup);
    }

    public function addSalad(string $salad): void
    {
        $this->builder->salad($salad);
    }
}

・index.php

<?php
require_once 'DinnerBuilder.php';
require_once 'Director.php';

$builder1 = new DinnerBuilder();
$director1 = new Director($builder1);
$director1->makeSteakSetMeal();

var_dump($builder1);

$builder2 = new DinnerBuilder();
$director2 = new Director($builder2);
$director2->addStapleFood("bread");
$director2->addMainDish("hamburg steak");
$director2->addSalad("caesar salad");

var_dump($builder2);

Builderパターンは実はeffective javaで紹介されているような物を良く使っていてあまりこちらで書いていないので他の人がこの書き方で書いているのを見た事があって混乱した覚えがあります。BuilderといってもLombok BuilderやFluent Builderというのもあるみたいです。複雑ですね…

(参考)
Head Firstデザインパターン ―頭とからだで覚えるデザインパターンの基本
2005/12/2
Eric Freeman (著), Elisabeth Freeman (著), Kathy Sierra (著), Bert Bates (著), 佐藤 直生 (監訳), 木下 哲也 (翻訳), 有限会社 福龍興業 (翻訳)
13章 付録:残りのパターン

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です