Composite パターン | デザインパターン
2022年9年24日
デザインパターン
Composite
PHP
オライリージャパンによる Head First シリーズ デザインパターン(第2版)第9章 Composite パターンを、PHPで書き直してみようという試みです。
MenuItem.php
namespace Composite; class MenuItem extends MenuComponent { public string $name; public string $description; public bool $vegetarian; public float $price; public function __construct(string $name, string $description, bool $vegetarian, float $price) { $this->name = $name; $this->description = $description; $this->vegetarian = $vegetarian; $this->price = $price; } public function getName() : string { return $this->name; } public function getDescription() : string { return $this->description; } public function getPrice() : float { return $this->price; } public function isVegetarian() : bool { return $this->vegetarian; } public function print() : void { echo self::getName(); echo (self::isVegetarian() ? '(v)' : null); echo '、' . self::getPrice() . "\n"; echo ' -- ' . self::getDescription() . "\n"; } }
Menu.php
namespace Composite; class Menu extends MenuComponent { public array $menuComponents = []; public string $name; public string $description; public function __construct(string $name, string $description) { $this->name = $name; $this->description = $description; } public function add(MenuComponent $menuComponent) : void { $this->menuComponents[] = $menuComponent; } public function remove(int $i) : void { unset($this->menuComponents[$i]); } public function getChild(int $i) : MenuComponent { return $this->menuComponents[$i]; } public function getName() : string { return $this->name; } public function getDescription() : string { return $this->description; } public function print() : void { echo "\n" . self::getName(); echo '、' . self::getDescription() . "\n"; echo '-------------------------' . "\n"; foreach($this->menuComponents as $menuComponent) { $menuComponent->print(); } }
MenuComponent.php
namespace Composite; abstract class MenuComponent { public function add(MenuComponent $menuComponent) : void { throw new Exception('UnsupportedOperationException',500); } public function remove(int $i) : void { throw new Exception('UnsupportedOperationException',500); } public function getChild(int $i) : MenuComponent { throw new Exception('UnsupportedOperationException',500); } public function getName() : string { throw new Exception('UnsupportedOperationException',500); } public function getDescription() : string { throw new Exception('UnsupportedOperationException',500); } public function getPrice() : float { throw new Exception('UnsupportedOperationException',500); } public function isVegetarian() : bool { throw new Exception('UnsupportedOperationException',500); } public function print() : void { throw new Exception('UnsupportedOperationException',500); } }
Waitress.php
namespace Composite; class Waitress { public MenuComponent $allMenus; public function __construct(MenuComponent $allMenus) { $this->allMenus = $allMenus; } public function printMenu() : void { $this->allMenus->print(); } }
index.php
出力結果
すべてのメニュー、全てを統合したメニュー ------------------------- パンケーキハウスメニュー、朝食 ------------------------- K&Bのパンケーキ朝食(v)、2.99 -- スクランブルエッグとトースト付きパンケーキ いつものパンケーキ朝食、2.99 -- 卵焼きとソーセージ付きパンケーキ ブルーベリーパンケーキ(v)、3.49 -- 新鮮なブルーベリーを使ったパンケーキ ワッフル(v)、3.59 -- ブルーベリーかいちごの好きな方を乗せたワッフル 食堂メニュー、昼食 ------------------------- ベジタリアンBTL(v)、2.99 -- レタス、トマト、(フェイク)ベーコンを挟んだ小麦パンサンドイッチ BLT、2.99 -- レタス、トマト、ベーコンを挟んだ小麦パンサンドイッチ 本日のスープ、3.29 -- ポテトサラダを添えた本日のスープ Hot Dog、3.05 -- ザワークラウト、レリッシュ、玉ねぎ、チーズを挟んだホットドッグ パスタ(v)、3.89 -- マリナラソーススパゲッティとサワードウパン デザートメニュー、もちろんデザート! ------------------------- アップルパイ(v)、1.59 -- バニラアイスクリームをのせたフレーク上生地のアップルパイ チーズケーキ(v)、1.99 -- チョコレートグラハム生地のクリーミーなニューヨークチーズケーキ シャーベット(v)、1.89 -- ラズベリーシャーベットとライムシャーベット カフェメニュー、夕食 ------------------------- 野菜バーガーとフライドポテト(v)、3.99 -- 小麦パンにレタスとトマトを挟んだ野菜バーガーとフライドポテト 本日のスープ、2.99 -- サラダがついた本日のスープ ブリトー(v)、4.29 -- インゲン豆、サルサ、グアカモーレ入りの大きなブリトー