DPDesign Pattern Quest
#05 / 23
C生成DIFF

プロトタイプ

Prototype

ハンコと同じ。1個だけ職人技で作って、あとは押すだけ。0から彫り直す必要はない。

Intent · 目的

オブジェクトを『種類』ではなく『雛形そのもの』で表現する。新しいインスタンスは、できあいの雛形を複製して作る。クラスを増やさずバリエーションを増やせて、しかも生成コストの高いオブジェクトも安く量産できる。

Motivation · 動機

ゲームで『敵キャラを 1000 体出す』場面。1体作るのに、テクスチャ読込・物理設定・AI初期化で重い処理が走る。それを1000回繰り返したら起動だけで日が暮れる。プロトタイプなら『最初の1体』だけ丁寧に作って、あとは `clone()` で複製。さらに『緑色のスライム』『赤色のスライム』みたいな微妙なバリエーションも、クラスを増やさず雛形の値を変えて持つだけで済む。

適用場面

  • 1生成コストが高く、初回1度作って以降コピーで済ませたい場合(ゲームのキャラ、レンダリング済みグラフィック)。
  • 2実行時にオブジェクトの種類が動的に決まる場合(ユーザー入力でモンスターのバリエーションを動的生成)。
  • 3クラス数を抑えながら多様なバリエーションを扱いたい場合。

概念図

サンプルコード

interface Cloneable<T> {
  clone(): T;
}

class Circle implements Cloneable<Circle> {
  constructor(public x: number, public y: number, public r: number) {}
  clone(): Circle { return new Circle(this.x, this.y, this.r); }
  render() { console.log(`Circle(${this.x},${this.y},${this.r})`); }
}

const original = new Circle(10, 20, 5);
const dup = original.clone();
dup.render();
Pros · メリット
  • クラス階層を増やさず、バリエーションは『状態違いの雛形』として表現できる。
  • 重い初期化処理が1回で済む。コピーは memcpy みたいなコストになることが多い。
  • 実行時にプロトタイプを差し替えれば、生成される『種』を動的に変えられる。
Cons · デメリット
  • シャローコピーかディープコピーかの判断ミスは事故の元。『片方を変えたらもう片方も変わってる』典型バグの源。
  • 循環参照やシリアライズ不能な状態(DB接続、ファイルハンドル)を含むと複製が困難。
  • 言語のクローン機構の癖(Java の `Cloneable` の闇は有名)に振り回されがち。

関連パターン

⚔ ready to test

理解度を確かめる時間だ

3 問のクイズで、 このパターンを身体に染み込ませよう。

挑戦する →