Builderパターン
複雑なインスタンスを構築する。
Builderクラスが構築のためのメソッドを定義。
Directorクラスがそのメソッドを使ってインスタンスを構築する。
具体的な処理はBuilderクラスのサブクラスが決める。
DirectorはBuilderのメソッドのみを使う。
実際に渡されるサブクラス(TextBuilder、HTMLBuilder)がどれかは知らない。
知らないからこそ、入れ替えができる。
Builder.php
abstract class Builder {
abstract function makeTitle(string $title): void;
abstract function makeString(string $str): void;
abstract function makeItems(array $items): void;
abstract function close(): void;
}
Director.php
class Director {
private $builder;
function __construct(Builder $builder) {
$this->builder = $builder;
}
function construct(): void {
$this->builder->makeTitle("あいさつ");
$this->builder->makeString("午前");
$this->builder->makeItems(["おはよう","こんにちは"]);
$this->builder->makeString("午後");
$this->builder->makeItems(["こんばんは","おやすみ","さよなら"]);
$this->builder->close();
}
}
TextBuilder.php
class TextBuilder extends Builder {
private $buffer = "";
function makeTitle(string $title): void {
$this->buffer .= "==========\n"
. "『".$title."』\n\n";
}
function makeString(string $str): void {
$this->buffer .= "■".$str."\n\n";
}
function makeItems(array $items): void {
foreach ($items as $item) {
$this->buffer .= " ・".$item."\n";
}
$this->buffer .= "\n";
}
function close(): void {
$this->buffer .= "==========\n";
}
function getResult(): string {
return $this->buffer;
}
}
HTMLBuilder.php
class HTMLBuilder extends Builder {
private $filename;
private $buffer = "";
function makeTitle(string $title): void {
$this->filename = $title.".html";
$this->buffer .= "<html><head><title>".$title."</title></head><body>"
. "<h1>".$title."</h1>";
}
function makeString(string $str): void {
$this->buffer .= "<p>".$str."</p>";
}
function makeItems(array $items): void {
$this->buffer .= "<ul>";
foreach ($items as $item) {
$this->buffer .= "<li>".$item."</li>";
}
$this->buffer .= "</ul>";
}
function close(): void {
$this->buffer .= "</body></html>";
file_put_contents($this->filename, $this->buffer);
}
function getResult(): string {
return $this->filename;
}
}
Main.php
require "../autoload.php";
if (!isset($argv[1])) {
echo "引数を指定してください\nphp Main.php [plain/html]";
return;
}
if ($argv[1] == "plain") {
$textBuilder = new TextBuilder();
$director = new Director($textBuilder);
$director->construct();
echo $textBuilder->getResult();
} else if ($argv[1] == "html") {
$htmlBuilder = new HTMLBuilder();
$director = new Director($htmlBuilder);
$director->construct();
$filename = $htmlBuilder->getResult();
echo $filename . "が作成されました";
}
autoload.php
function autoload($className){
require './'.$className.'.php';
}
spl_autoload_register('autoload');