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");
出力結果
ぶちスライム ファーラット マンドラゴラ ファーラット(クローン) ファーラット(クローン) マンドラゴラ(クローン) マンドラゴラ(クローン) ぶちスライム(クローン) ムドー ムドー(幻)(クローン) ムドー(現実)(クローン)