Builder パターンとは
オブジェクトの生成過程を抽象化することによって、動的なオブジェクトの生成を可能にする。
example
以下は、Builderパターンで文書を作成するサンプルプログラム。
Builder 抽象クラス
<?php abstract class Builder { abstract public function makeTitle(string $title); abstract public function makeString(string $str); abstract public function makeItems(array $items); abstract public function close(); }
Director クラス
<?php class Director { private $builder; public function __construct(Builder $builder) { $this->builder = $builder; } public function create() { $this->builder->makeTitle("Greeting"); $this->builder->makeString("朝から昼にかけて"); $this->builder->makeItems([ "おはようございます。", "こんにちは。", ]); $this->builder->makeString("夜に"); $this->builder->makeItems([ "こんばんは。", "おやすみなさい。", "さようなら。", ]); $this->builder->close(); } }
HTMLBuilder クラス
<?php class HTMLBuilder extends Builder { private $filename; private $writer; public function makeTitle(string $title) { $this->filename = $title . ".html"; try { $this->writer = fopen($this->filename, 'w'); } catch (Exception $e) { $e->getTrace(); } $this->write("<html><head><title>" . $title . "</title></head><body>"); $this->write("<h1>" . $title . "</h1>"); } public function makeString(string $str) { $this->write("<p>" . $str . "</p>"); } public function makeItems(array $items) { $this->write("<ul>"); for ($i = 0; $i < count($items); $i++) { $this->write("<li>" . $items[$i] . "</li>"); } $this->write("</ul>"); } public function write(string $str) { fwrite($this->writer, $str . PHP_EOL); } public function close() { $this->write("</body></html>"); fclose($this->writer); } public function getResult(): string { return $this->filename; } }
TextBuilder クラス
<?php class TextBuilder extends Builder { private $buffer = ""; public function makeTitle(string $title) { $this->append("==============================\n"); $this->append("『" . $title . "』\n"); $this->append(PHP_EOL); } public function makeString(string $str) { $this->append('■' . $str . PHP_EOL); $this->append(PHP_EOL); } public function makeItems(array $items) { for ($i = 0; $i < count($items); $i++) { $this->append(" ・" . $items[$i] . PHP_EOL); } $this->append(PHP_EOL); } public function close() { $this->append("==============================\n"); } public function getResult(): string { return $this->buffer; } public function append(string $str) { $this->buffer .= $str; } }
Main
<?php echo "1:plain, 2:html :"; $input = intval(trim(fgets(STDIN))); if ($input === 1) { $textbuilder = new TextBuilder(); $director = new Director($textbuilder); $director->create(); $result = $textbuilder->getResult(); echo $result; } elseif ($input === 2) { $htmlbuilder = new HTMLBuilder(); $director = new Director($htmlbuilder); $director->create(); $filename = $htmlbuilder->getResult(); echo $filename . "が作成されました。"; } else { usage(); exit; } function usage() { echo "Usage: plain プレーンテキストで文書作成"; echo PHP_EOL; echo "Usage: html HTMLファイルで文書作成"; }
実行結果1
$ php Main.php 1:plain, 2:html :1 ============================== 『Greeting』 ■朝から昼にかけて ・おはようございます。 ・こんにちは。 ■夜に ・こんばんは。 ・おやすみなさい。 ・さようなら。 ==============================
実行結果2
$ php Main.php 1:plain, 2:html :2 Greeting.htmlが作成されました。#
ソースコード
役割
- Builder: インスタンス生成のためのインターフェースを定める。サンプルではBuilderクラス。
- ConcreteBuilder: Builder役のインターフェースを実装するクラス。サンプルではTextBuilder,HTMLBuilderクラス。
- Director: Builder役のインターフェースを使ってインスタンスを生成する役割。Builder役のメソッドのみを利用すr。サンプルではDirectorクラス。
まとめ
- オブジェクト指向プログラミンでは「誰が何を知っているか」がとても重要。
- 何を利用しているか「知らない」ということは、「入れ替え可能」ということ。交換可能性(入れ替えができるかどうか)は常に意識して設計を行う必要がある。
関連パターン
- PHP7でデザインパターン入門3/23 Template Methodパターン - Do Something
- PHP7でデザインパターン入門11/23 Compositeパターン - Do Something
- PHP7でデザインパターン入門8/23 Abstract Factoryパターン - Do Something
- PHP7でデザインパターン入門15/23 Facadeパターン - Do Something
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
- 購入: 51人 クリック: 762回
- この商品を含むブログ (399件) を見る