抽象的な工場では、抽象的な部品を組み合わせて抽象的な製品をつくる
具体的な実装には注目せず、インタフェースだけを使って、部品を組み立て、製品にまとめる
具体的な工場を新たに追加するのは簡単
部品を新たに追加するのは困難(すべての具体的な工場に追加する必要があるので)
Factory.php
abstract class Factory {
static function getFactory($classname): Factory {
try {
return new $classname();
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
}
abstract function createLink($caption, $url): Link;
abstract function createTray($caption): Tray;
abstract function createPage($title, $author): Page;
}
Item.php
abstract class Item {
protected $caption;
function __construct($caption) {
$this->caption = $caption;
}
abstract function makeHTML();
}
Link.php
abstract class Link extends Item {
protected $url;
function __construct($caption, $url) {
parent::__construct($caption);
$this->url = $url;
}
}
Tray.php
abstract class Tray extends Item {
protected $tray = [];
function __construct($caption) {
parent::__construct($caption);
}
function add(Item $item) {
$this->tray[] = $item;
}
}
Page.php
abstract class Page {
protected $title;
protected $author;
protected $content = [];
function __construct($title, $author) {
$this->title = $title;
$this->author = $author;
}
function add(Item $item) {
$this->content[] = $item;
}
function output() {
try {
$filename = $this->title . ".html";
file_put_contents($filename, $this->makeHTML());
echo $filename . "を作成しました。\n";
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
}
abstract function makeHTML();
}
Main.php
require "../autoload.php";
if (!isset($argv[1])) {
echo "引数を指定してください\nphp Main.php [ListFactory/TableFactory]\n";
return;
}
$factory = Factory::getFactory($argv[1]);
$twitter = $factory->createLink("twitter", "https://twitter.com/lightwill0309");
$youtube = $factory->createLink("youtube", "https://www.youtube.com/@lightwill");
$guitarflix = $factory->createLink("ギターフリックス", "https://lightwill.tokyo/guitarflix/");
$dramamegra = $factory->createLink("ドラマメグラ", "https://dramamegra.com/");
$traySns = $factory->createTray("SNS");
$traySns->add($twitter);
$traySns->add($youtube);
$trayWeb = $factory->createTray("Webサービス");
$trayWeb->add($guitarflix);
$trayWeb->add($dramamegra);
$page = $factory->createPage("LinkPage", "lightwill");
$page->add($traySns);
$page->add($trayWeb);
$page->output();
ListFactory.php
class ListFactory extends Factory {
function createLink($caption, $url): Link {
return new ListLink($caption, $url);
}
function createTray($caption): Tray {
return new ListTray($caption);
}
function createPage($title, $author): Page {
return new ListPage($title, $author);
}
}
ListLink.php
class ListLink extends Link {
function __construct($caption, $url) {
parent::__construct($caption, $url);
}
function makeHTML() {
return ' <li><a href="' . $this->url . '">' . $this->caption . "</a></li>\n";
}
}
ListTray.php
class ListTray extends Tray {
function __construct($caption) {
parent::__construct($caption);
}
function makeHTML() {
$html = "<li>\n" . $this->caption . "\n<ul>\n";
foreach ($this->tray as $item) {
$html .= $item->makeHTML();
}
$html .= "</ul>\n</li>\n";
return $html;
}
}
ListPage.php
class ListPage extends Page {
function __construct($title, $author) {
parent::__construct($title, $author);
}
function makeHTML() {
$html = "<html><head><title>" . $this->title . "</title></head>\n"
. "<body>\n<h1>" . $this->title . "</h1>\n<ul>\n";
foreach ($this->content as $item) {
$html .= $item->makeHTML();
}
$html .= "</ul>\n<hr><address>" . $this->author . "</address></body></html>\n";
return $html;
}
}
TableFactory.php
class TableFactory extends Factory {
function createLink($caption, $url): Link {
return new TableLink($caption, $url);
}
function createTray($caption): Tray {
return new TableTray($caption);
}
function createPage($title, $author): Page {
return new TablePage($title, $author);
}
}
TableLink.php
class TableLink extends Link {
function __construct($caption, $url) {
parent::__construct($caption, $url);
}
function makeHTML() {
return ' <td><a href="' . $this->url . '">' . $this->caption . "</a></td>\n";
}
}
TableTray.php
class TableTray extends Tray {
function __construct($caption) {
parent::__construct($caption);
}
function makeHTML() {
$html = "<td><table><tr><td>" . $this->caption . "</td></tr>\n<tr>\n";
foreach ($this->tray as $item) {
$html .= $item->makeHTML();
}
$html .= "</tr></table></td>";
return $html;
}
}
TablePage.php
class TablePage extends Page {
function __construct($title, $author) {
parent::__construct($title, $author);
}
function makeHTML() {
$html = "<html><head><title>" . $this->title . "</title></head>\n"
. "<body>\n<h1>" . $this->title . "</h1>\n<table>\n";
foreach ($this->content as $item) {
$html .= "<tr>" . $item->makeHTML() . "</tr>";
}
$html .= "</table>\n<hr><address>" . $this->author . "</address></body></html>\n";
return $html;
}
}