👻

デザインパターンを学ぶ #15 Prototype(プロトタイプ)

に公開

1. はじめに

今回は Prototype(プロトタイプ)パターン
目的は、既存のオブジェクトをコピーして新しいオブジェクトを作ることです。

コンストラクタで複雑な初期化が必要なオブジェクトでも、ひな形(プロトタイプ)から複製することで高速かつ柔軟に生成できます。

2. Prototypeとは?

プロトタイプパターンは、**オブジェクトの生成を new ではなく「複製」で行う」**という考え方です。

  • 同じ構造・値を持ったインスタンスを複数作りたい
  • clone() などを使ってコピーする

というような場面で使われます。

主な登場役は以下の2つです:

  • Prototype(原型) … 自分自身を複製できる
  • Client(利用側) … Prototypeを複製して利用する

3. 実装イメージ(PHP)

<?php
// Prototype(原型)
abstract class DocumentPrototype {
    public function __construct(
        protected string $title,
        protected string $content
    ) {}
    abstract public function copy(): static;

    public function dump(): string {
        return "{$this->title}: {$this->content}";
    }
}

// ConcretePrototype(具体的原型)
class Report extends DocumentPrototype {
    public function copy(): static {
        return clone $this;
    }
}

// --- 実行例 ---
$report1 = new Report('週報', '今週の進捗...');
$report2 = $report1->copy();
$report3 = $report1->copy();

echo $report1->dump(), PHP_EOL; // 週報: 今週の進捗...
echo $report2->dump(), PHP_EOL; // 週報: 今週の進捗...
echo $report3->dump(), PHP_EOL; // 週報: 今週の進捗...

4. メリット・デメリット

メリット

  • 複雑な初期化処理を省略できる
  • new を使わずに柔軟にインスタンス生成できる

デメリット

  • 深いコピー・浅いコピーの扱いを間違えるとバグになる
  • 複雑なオブジェクトではコピー実装が難しい

5. 使いどころ

  • 複雑な初期化処理が必要なオブジェクトを大量に生成したいとき
  • テンプレート(ひな形)を元に複製して使いたいとき
  • インスタンス生成コストを下げたいとき

newせずに複製して作る」というアプローチが、プロトタイプパターンです。

Discussion