AbstractFactory パターン | デザインパターン
2022年9年23日
デザインパターン
AbstractFactory
PHP
オライリージャパンによる Head First シリーズ デザインパターン(第2版)第4章 AbstractFactory パターンを、PHPで書き直してみようという試みです。
PizzaStore.php
namespace AbstractFactory; abstract class PizzaStore { public function orderPizza(string $type){ $pizza = null; $pizza = $this->createPizza($type); $pizza->prepare(); $pizza->bake(); $pizza->cut(); $pizza->box(); return $pizza; } abstract public function createPizza(string $type); }
NYPizzaStore.php
namespace AbstractFactory; class NYPizzaStore extends PizzaStore { public function createPizza(string $type){ $pizza = null; $ingredientFactory = new NYPizzaIngredientFactory(); if ($type === 'チーズ') { $pizza = new CheesePizza($ingredientFactory); $pizza->setName('ニューヨークスタイルチーズピザ'); } else if($type === '野菜') { $pizza = new VeggiesPizza($ingredientFactory); $pizza->setName('ニューヨークスタイル野菜ピザ'); } else if($type === 'アサリ') { $pizza = new ClamPizza($ingredientFactory); $pizza->setName('ニューヨークスタイルアサリピザ'); } else if($type === 'ペパロニ') { $pizza = new PepperoniPizza($ingredientFactory); $pizza->setName('ニューヨークスタイルペパロニピザ'); } return $pizza; } }
ChicagoPizzaStore.php
namespace AbstractFactory; class ChicagoPizzaStore extends PizzaStore { public function createPizza(string $type){ $pizza = null; $ingredientFactory = new ChicagoPizzaIngredientFactory(); if ($type === 'チーズ') { $pizza = new CheesePizza($ingredientFactory); $pizza->setName('シカゴスタイルチーズピザ'); } else if($type === '野菜') { $pizza = new VeggiesPizza($ingredientFactory); $pizza->setName('シカゴスタイル野菜ピザ'); } else if($type === 'アサリ') { $pizza = new ClamPizza($ingredientFactory); $pizza->setName('シカゴスタイルアサリピザ'); } else if($type === 'ペパロニ') { $pizza = new PepperoniPizza($ingredientFactory); $pizza->setName('シカゴスタイルペパロニピザ'); } return $pizza; } }
Pizza.php
namespace AbstractFactory; abstract class Pizza { public string $name = ''; public Dough $dough; public Sauce $sauce; public Cheese $cheese; public array $veggies; public Pepperoni $pepperoni; public Clams $clam; abstract function prepare() : void; public function bake() : void { echo '180度で25分焼く' . "\n"; } public function cut() : void { echo 'ピザを扇型にカットする' . "\n"; } public function box() : void { echo 'PizzaStoreの箱にピザを入れる' . "\n"; } public function setName(string $name) : void { $this->name = $name; } public function getName() : string { return $this->name; } }
CheesePizza.php
namespace AbstractFactory; class CheesePizza extends Pizza { public PizzaIngredientFactory $ingredientFactory; public function __construct(PizzaIngredientFactory $ingredientFactory) { $this->ingredientFactory = $ingredientFactory; } public function prepare() : void { echo $this->name . 'を調理' . "\n"; $this->dough = $this->ingredientFactory->createDough(); echo $this->dough->getDough() . 'をこねる' . "\n"; $this->sauce = $this->ingredientFactory->createSauce(); echo $this->sauce->getSauce() . 'を追加' . "\n"; $this->cheese = $this->ingredientFactory->createCheese(); echo $this->cheese->getCheese() . 'をトッピング' . "\n"; } }
Soy.php
namespace AbstractFactory; interface PizzaIngredientFactory { public function createDough() : Dough; public function createSauce() : Sauce; public function createCheese() : Cheese; public function createVehhies() : array; public function createPepperoni() : Pepperoni; public function createClams() : Clams; }
NYPizzaIngredientFactory.php
namespace AbstractFactory; class NYPizzaIngredientFactory implements PizzaIngredientFactory { public function createDough() : Dough { return new ThinCrustDough(); } public function createSauce() : Sauce { return new MarinaraSauce(); } public function createCheese() : Cheese { return new ReggianoCheese(); } public function createVehhies() : array { $veggies = [new Garlic(), new Onion(), new MushRoom(), new RedPepper()]; return $veggies; } public function createPepperoni() : Pepperoni { return new SlicedPepperoni(); } public function createClams() : Clams { return new FreshClams(); } }
ChicagoPizzaIngredientFactory.php
namespace AbstractFactory; class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory { public function createDough() : Dough { return new ThickCrustDough(); } public function createSauce() : Sauce { return new PlumTomatoSauce(); } public function createCheese() : Cheese { return new MozzarellaCheese(); } public function createVehhies() : array { $veggies = [new BlackOlives(), new Spinach(), new Eggplant()]; return $veggies; } public function createPepperoni() : Pepperoni { return new SlicedPepperoni(); } public function createClams() : Clams { return new FrozenClams(); } }
Dough.php
namespace AbstractFactory; interface Dough { public function getDough() : string; }
ThinCrustDough.php
namespace AbstractFactory; class ThinCrustDough implements Dough { public function getDough() : string { return 'うすい生地'; } }
ThickCrustDough.php
namespace AbstractFactory; class ThickCrustDough implements Dough { public function getDough() : string { return '厚い生地'; } }
Sauce.php
namespace AbstractFactory; interface Sauce { public function getSauce() : string; }
MarinaraSauce.php
namespace AbstractFactory; class MarinaraSauce implements Sauce { public function getSauce() : string { return 'マリナラソース'; } }
PlumTomatoSauce.php
namespace AbstractFactory; class PlumTomatoSauce implements Sauce { public function getSauce() : string { return 'プラムトマトソース'; } }
Cheese.php
namespace AbstractFactory; interface Cheese { public function getCheese() : string; }
ReggianoCheese.php
namespace AbstractFactory; class ReggianoCheese implements Cheese { public function getCheese() : string { return 'すりおろしたレッジャーノチーズ'; } }
MozzarellaCheese.php
namespace AbstractFactory; class MozzarellaCheese implements Cheese { public function getCheese() : string { return 'シュレッドモッツァレラチーズ'; } }
index.php
use AbstractFactory\NYPizzaStore; use AbstractFactory\ChicagoPizzaStore; $nyStore = new NYPizzaStore(); $chicagoStore = new ChicagoPizzaStore(); $pizza = $nyStore->orderPizza('チーズ'); echo 'イーサンの注文は' . $pizza->getName() . "\n\n"; $pizza = $chicagoStore->orderPizza('チーズ'); echo 'ジョエルの注文は' . $pizza->getName() . "\n\n";
出力結果
ニューヨークスタイルチーズピザを調理 うすい生地をこねる マリナラソースを追加 すりおろしたレッジャーノチーズをトッピング 180度で25分焼く ピザを扇型にカットする PizzaStoreの箱にピザを入れる イーサンの注文はニューヨークスタイルチーズピザ シカゴスタイルチーズピザを調理 厚い生地をこねる プラムトマトソースを追加 シュレッドモッツァレラチーズをトッピング 180度で25分焼く ピザを扇型にカットする PizzaStoreの箱にピザを入れる ジョエルの注文はシカゴスタイルチーズピザ