GoF本 Prototype
まとめ
- newとかするのではなく、作り置きしたオブジェクトを
Clone()
する
モチベーション
- AbstractFactoryやFactoryMethodを導入すると、
AbstractFactory
やCreator
のサブクラスを大量に定義することになる- 管理が大変
- 実行時に動的に追加できない
これらをなんとかしたい
登場人物
- Prototype
- 生成対象のオブジェクトのインタフェース
Clone()
を定義
- 生成対象のオブジェクトのインタフェース
- ConcretePrototype
- Prototypeを実装
Clone()
を実装
- Prototypeを実装
- Client
prototype.Clone()
を実行し、オブジェクトを複製する人prototype.Initialize(..args)
を呼び出して初期化を行ったりもする
- PrototypeManager
- クラスではない
- キー => Prototypeオブジェクト の辞書
- Clientが利用する
つかいどころ
- 生成すべきオブジェクトが実行時に定まる(静的にわからない)
- 動的にロードを行うとか
- 生成すべきオブジェクトのクラスツリーと並列な、ファクトリのクラスツリーを作りたくない
- 生成すべきオブジェクトの状態があまり違わない
- 四分音符と全音符とか
功罪
- 実行時に生成すべきオブジェクトを追加できる
- お絵描きソフトで、ユーザ定義テンプレートを追加できる、とか
- JSのプロトタイプベースの継承みたいなことがC++のような言語でもできる
- これはPrototypeパターン関係ない気がする
Strategyとかのほうが関係が深いのでは
- これはPrototypeパターン関係ない気がする
- サブクラスを減らせる
- FactoryMethod等
- Prototypeオブジェクトの辞書
partCatalog
メンバを持たせる実装にすることで、
Creatorクラスツリーが要らなくなる
- Prototypeオブジェクトの辞書
- JS等、クラスが第一級オブジェクトの場合はクラスの辞書にすればいいのでPrototypeパターンの出る幕はない
- FactoryMethod等
実装
- Prototypeオブジェクトの辞書を用意すると良い(PrptotypeManager)
Clone()
の実装がキモ- 循環参照があったりするとやばい
- Deep Copy
- Save/Load処理があるのなら、それを使うと楽
- オブジェクトを生成するにあたり、クローンそのままでよいこともあれば、パラメータを与えて初期化が必要なケースもある
- 生成するオブジェクトによって必要なバラメータは当然異なるので、複製処理のインタフェースを統一することは難しい
- ので、
Clone()
後Initialize(...args)
を呼ぶようにし、Clone()
のインタフェースは統一する
関連するパターン
- AbstractFactoryパターン
- 競合するパターン
- だが、AbstractFactoryをPrototypeパターンで実装することもできる
- ConcreteFactoryを大量に作らなくてよくなる
- CompositeパターンやDecoratorパターンを多用している場合、Prototypeパターン導入の恩恵が大きい