Prototype パターン | デザインパターン
2022年9年28日
デザインパターン
Prototype
PHP
オライリージャパンによる Head First シリーズ デザインパターン(第2版)第14章 Prototype パターンを、 PHPで書き直してみようという試みです。
Monster.php
namespace Prototype; abstract class Monster { public string $name; private bool $copied; public function __construct(string $name) { $this->name = $name; $this->copied = false; } abstract protected function __clone(); public function clone() : Monster { return clone $this; } public function setName(string $name) : void { $this->name = $name; } public function setCopied(bool $copied) : void { $this->copied = $copied; } public function toString() : string { return $this->name . ($this->copied ? '(クローン)' : NULL) . "\n"; } }
WellKnownMonster.php
namespace Prototype; class WellKnownMonster extends Monster { protected function __clone() { $this->setCopied(true); } }
DynamicPlayerGeneratedMonster.php
namespace Prototype; class DynamicPlayerGeneratedMonster extends Monster { protected function __clone() { $this->setCopied(true); } public function setName(string $name) : void { $this->name = $name; } }
MonsterRegistry.php
namespace Prototype; class MonsterRegistry { private array $registered = []; private int $count = 0; public function getMonster() : Monster { $correctMonster = $this->registered[rand(0, $this->count - 1)]; return $correctMonster->clone(); } public function setMonster(Monster $monster) : void { $this->registered[$this->count] = $monster; $this->count++; } }
MonsterMaker.php
namespace Prototype; class MonsterMaker { public function __construct(MonsterRegistry $monsterRegistry) { $this->monsterRegistry = $monsterRegistry; } public function makeRandomMonster() : Monster { return $this->monsterRegistry->getMonster(); } }
index.php
use Prototype\WellKnownMonster; use Prototype\DynamicPlayerGeneratedMonster; use Prototype\MonsterRegistry; use Prototype\MonsterMaker; $wellKnownMonster1 = new WellKnownMonster('ぶちスライム'); $wellKnownMonster2 = new WellKnownMonster('ファーラット'); $wellKnownMonster3 = new WellKnownMonster('マンドラゴラ'); echo($wellKnownMonster1->toString()); echo($wellKnownMonster2->toString()); echo($wellKnownMonster3->toString()); echo("\n"); $monsterRegistry = new MonsterRegistry(); $monsterRegistry->setMonster($wellKnownMonster1); $monsterRegistry->setMonster($wellKnownMonster2); $monsterRegistry->setMonster($wellKnownMonster3); $monsterMaker = new MonsterMaker($monsterRegistry); $monster1 = $monsterMaker->makeRandomMonster(); $monster2 = $monsterMaker->makeRandomMonster(); $monster3 = $monsterMaker->makeRandomMonster(); $monster4 = $monsterMaker->makeRandomMonster(); $monster5 = $monsterMaker->makeRandomMonster(); echo($monster1->toString()); echo($monster2->toString()); echo($monster3->toString()); echo($monster4->toString()); echo($monster5->toString()); echo("\n"); $generatedMonster = new DynamicPlayerGeneratedMonster('ムドー'); echo($generatedMonster->toString()); echo("\n"); $monsterRegistry = new MonsterRegistry(); $monsterRegistry->setMonster($generatedMonster); $monsterMaker = new MonsterMaker($monsterRegistry); $monster1 = $monsterMaker->makeRandomMonster(); $monster2 = $monsterMaker->makeRandomMonster(); $monster1->setName('ムドー(幻)'); $monster2->setName('ムドー(現実)'); echo($monster1->toString()); echo($monster2->toString()); echo("\n");
出力結果
ぶちスライム ファーラット マンドラゴラ ファーラット(クローン) ファーラット(クローン) マンドラゴラ(クローン) マンドラゴラ(クローン) ぶちスライム(クローン) ムドー ムドー(幻)(クローン) ムドー(現実)(クローン)