本記事に掲載したサンプルコードは、https://github.com/ryo-utsunomiya/design_patternでも公開中です。
Builderとは
Builderとは、構造を持ったインスタンスを組み上げるパターンです。
ここでは、文書を構成するためのBuilderクラスと、Builderクラスを使って文書を組み上げるDirectoryクラスを実装します。
まず、Builderの挙動を定めたインタフェースを作成します。
<?php
namespace my;
interface Builder
{
/**
* @param string $title
*/
public function makeTitle($title);
/**
* @param string $str
*/
public function makeString($str);
/**
* @param array $items
*/
public function makeItems(array $items);
public function close();
}
次に、Directorを実装します。Directoryは、Builderインタフェースのメソッドだけを実行します(「抽象に依存せよ」)。
<?php
namespace my;
class Director
{
/**
* @var Builder
*/
private $builder;
/**
* @param Builder $builder
*/
public function __construct(Builder $builder)
{
$this->builder = $builder;
}
public function construct()
{
$this->builder->makeTitle('Greeting');
$this->builder->makeString('From morning to noon');
$this->builder->makeItems(
[
'Good Morning',
'Hello',
]
);
$this->builder->makeString('At night');
$this->builder->makeItems(
[
'Good evening',
'Good night',
'Good bye',
]
);
$this->builder->close();
}
}
これで、「文書を構成する仕組みの骨組み」と、「文書を実際に作成する処理」が出来ました。次に、実際に文書を作成する処理を実装します。
<?php
namespace my;
class TextBuilder implements Builder
{
/**
* @var string
*/
private $string = '';
/**
* @param string $title
*/
public function makeTitle($title)
{
$this->drawLine();
$this->string .= '# ' . $title . PHP_EOL;
$this->string .= PHP_EOL;
}
/**
* @param string $str
*/
public function makeString($str)
{
$this->string .= '## ' . $str . PHP_EOL;
$this->string .= PHP_EOL;
}
/**
* @param array $items
*/
public function makeItems(array $items)
{
foreach ($items as $item) {
$this->string .= '* ' . $item . PHP_EOL;
}
$this->string .= PHP_EOL;
}
public function close()
{
$this->drawLine();
}
/**
* @return string
*/
public function getResult()
{
return $this->string;
}
private function drawLine()
{
$this->string .= str_repeat('=', 25) . PHP_EOL;
}
}
ここで実装した、TextBuilderクラスは、単純な文字列を組み立てるクラスです。Builderはインタフェースが定義されているので、必要に応じて、HtmlBuilderなどのクラスを実装することもできます。
TextBuilderを使用したコードは以下のようになります。
$textBuilder = new TextBuilder();
(new Director($textBuilder))->construct();
echo $textBuilder->getResult(), PHP_EOL;