抽象的な工場では、抽象的な部品を組み合わせて抽象的な製品をつくる
具体的な実装には注目せず、インタフェースだけを使って、部品を組み立て、製品にまとめる
具体的な工場を新たに追加するのは簡単
部品を新たに追加するのは困難(すべての具体的な工場に追加する必要があるので)
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;
}
}