Prototype パターンとは
生成されるオブジェクトの種別がプロトタイプ(典型)的なインスタンスであるときに使用され、このプロトタイプを複製して新しいオブジェクトを生成する。 このパターンは Abstract Factory パターンでなされるように、クライアント・アプリケーションにおいてオブジェクトの生成者をサブクラスにすることを回避する。 標準的な方法(例えば'new')で新しいオブジェクトを作ることによる固有のコストが所与のアプリケーションにとって高すぎる時にそれを回避する。
具体的には以下のような場合にインスタンスを複製して新しいインスタンスを生成するパターンのようだ。
example
以下サンプルプログラム。 文字列を枠線を囲って表示したり、下線を引いて表示したりするもの。
Framework/Manager クラス
<?php class Manager { private $showcase = []; public function register(string $name, Product $proto) { $this->showcase[$name] = $proto; } public function create(string $protoname): Product { $p = $this->showcase[$protoname]; return $p->createClone(); } }
Framework/Product インターフェース
<?php interface Product { public function use(string $s); public function createClone(): Product; }
UnderlinePen クラス
<?php class UnderlinePen implements Product { private $ulchar; public function __construct(string $ulchar) { $this->ulchar = $ulchar; } public function use(string $s) { $length = strlen(mb_convert_encoding($s, 'SJIS', 'UTF-8')); echo "\"{$s}\"" . PHP_EOL . " "; for ($i = 0; $i < $length; $i++) { echo $this->ulchar; } echo PHP_EOL; } public function createClone(): Product { $p = null; try { $p = clone $this; } catch (Exception $e) { $e->getTrace(); } return $p; } }
MessageBox クラス
<?php class MessageBox implements Product { private $decochar; public function __construct(string $decochar) { $this->decochar = $decochar; } public function use(string $s) { $length = strlen(mb_convert_encoding($s, 'SJIS', 'UTF-8')); for ($i = 0; $i < $length + 4; $i++) { echo($this->decochar); } echo PHP_EOL . "{$this->decochar} {$s} {$this->decochar}" . PHP_EOL; for ($i = 0; $i < $length + 4; $i++) { echo $this->decochar; } echo PHP_EOL; } public function createClone(): Product { $p = null; try { $p = clone $this; } catch (Exception $e) { $e->getTrace(); } return $p; } }
main
<?php $manager = new Manager(); $upen = new UnderlinePen('~'); $mbox = new MessageBox('*'); $sbox = new MessageBox('/'); $manager->register("strong message", $upen); $manager->register("warning box", $mbox); $manager->register("slash box", $sbox); $p1 = $manager->create("strong message"); $p1->use("Hello, world."); $p2 = $manager->create("warning box"); $p2->use("Hello, world."); $p3 = $manager->create("slash box"); $p3->use("Hello, world.");
実行結果
"Hello, world." ~~~~~~~~~~~~~ ***************** * Hello, world. * ***************** ///////////////// / Hello, world. / /////////////////
ソースコード
役割
- Product: framework. インターフェース。useとcreateCloneのみ宣言されている。
- Manager: framework. createCloneを使ってインスタンスを複製するクラス
- MessageBox: 文字列を枠線で囲って表示するクラス。Productインターフェースを実装している。
- UnderlinePen: 文字列に下線を引いて表示するクラス。Productをインターフェースを実装している。
まとめ
Prototypeは、インスタンスから新しいインスタンスを複製するパターンである。
関連パターン
- PHP7でデザインパターン入門20/23 Flyweightパターン - Do Something
- PHP7でデザインパターン入門18/23 Mementoパターン - Do Something
- PHP7でデザインパターン入門11/23 Compositeパターン - Do Something
- PHP7でデザインパターン入門22/23 Commandパターン - Do Something
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2004/06/19
- メディア: 大型本
- 購入: 51人 クリック: 762回
- この商品を含むブログ (399件) を見る