Prototype パターン

デザインパターンちゃんと勉強をしようと思ったので結城さんの本を 1 つ 1 つ実装してみる。 前回の Singletonからの続き。

Prototype パターン(英: Prototype pattern、プロトタイプ・パターン)とは、ソフトウェア開発で用いられる、生成に関するデザインパターンの 1 つである。生成されるオブジェクトの種別がプロトタイプ(典型)的なインスタンスであるときに使用され、このプロトタイプを複製して新しいオブジェクトを生成する。

なるほどわからん。

クラス図

Prototype PlantUML

ここは実際にどのような形で使われるかをみるのが分かりやすいと感じた。

<?php
$manager = new \prototype\Manager();

// 準備
$upen = new \prototype\UnderlinePen('~');
$mbox = new \prototype\MessageBox('*');
$sbox = new \prototype\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.");
?>

manager が、下線用(UndelinePen)や枠線用(MessageBox)などのインスタンスに「名前をつけて」登録して、その登録された名前を呼び出すことで処理を行なっている。

自分としての理解・疑問

  • なぜ必要なのかという質問が来た時に答えるのであれば「状態を持ったインスタンスの生成の管理」を楽にするため?
  • 複製までを manager 側が各インスタンスに指示をだしている。
  • 上記例の場合は「文字列を ○ 回数表示する」や「文字列を分割する」などどんどん機能が増えていった場合に manager 側が機能の数などは把握していなくて良い場合が多いという事だと思う。
  • あまりガチガチに実装を規定するというより纏めて管理しましょうといった感じ。

注意点

実装が書かれている UnderlinePen や MessageBox などは自分自身のクローンを作成する処理が入っているが、PHP の場合クローンを作成した場合シャローコピーなので、ディープコピーが必要な場合は __clone 等で保持している情報を適切に複製してあげる必要がある。

「状態をもったインスタンスの生成」がキモであるからそのインスタンスが他インスタンスに依存するような情報をもってたりするとハマりそう。

<?php
    public function createClone()
    {
        $p = null;
        try {
            // 自分自身のクローンを作成する
            $p = clone $this;
        } catch (Exception $e) {
            echo $e->getMessage() . "\n";
        }
        return $p;
    }

参考