プロトタイプ パターン

Prototype Pattern

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");
 

出力結果

 
  ぶちスライム
  ファーラット
  マンドラゴラ

  ファーラット(クローン)
  ファーラット(クローン)
  マンドラゴラ(クローン)
  マンドラゴラ(クローン)
  ぶちスライム(クローン)

  ムドー

  ムドー(幻)(クローン)
  ムドー(現実)(クローン)
 

だてめがね
...
©️ ponpocopy

とある企業で社内SEをしています。 自身の学びが誰かの為になれば、という想いで日々ブログを更新中。 PHP(CakePHP・Laravel・FuelPHP), Pyhotn(Django・Flask), C#(ASP.NET、Unity) が好きです。