forget for get

覚えるために忘れる

Builderパターン

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');