#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 問のクイズで、 このパターンを身体に染み込ませよう。