勉強日記

毎日投稿

GoF本 Prototype

まとめ

  • newとかするのではなく、作り置きしたオブジェクトをClone()する

モチベーション

  • AbstractFactoryFactoryMethodを導入すると、 AbstractFactoryCreatorのサブクラスを大量に定義することになる
    • 管理が大変
    • 実行時に動的に追加できない

これらをなんとかしたい

登場人物

  • Prototype
    • 生成対象のオブジェクトのインタフェース
      • Clone()を定義
  • ConcretePrototype
    • Prototypeを実装
      • Clone()を実装
  • Client
    • prototype.Clone()を実行し、オブジェクトを複製する人
    • prototype.Initialize(..args)を呼び出して初期化を行ったりもする
  • PrototypeManager
    • クラスではない
    • キー => Prototypeオブジェクト の辞書
    • Clientが利用する

つかいどころ

  • 生成すべきオブジェクトが実行時に定まる(静的にわからない)
    • 動的にロードを行うとか
  • 生成すべきオブジェクトのクラスツリーと並列な、ファクトリのクラスツリーを作りたくない
  • 生成すべきオブジェクトの状態があまり違わない
    • 四分音符と全音符とか

功罪

  • 実行時に生成すべきオブジェクトを追加できる
    • お絵描きソフトで、ユーザ定義テンプレートを追加できる、とか
  • JSのプロトタイプベースの継承みたいなことがC++のような言語でもできる
    • これはPrototypeパターン関係ない気がする
      Strategyとかのほうが関係が深いのでは
  • サブクラスを減らせる
    • FactoryMethod
      • Prototypeオブジェクトの辞書partCatalogメンバを持たせる実装にすることで、
        Creatorクラスツリーが要らなくなる
    • JS等、クラスが第一級オブジェクトの場合はクラスの辞書にすればいいのでPrototypeパターンの出る幕はない

実装

  • Prototypeオブジェクトの辞書を用意すると良い(PrptotypeManager)
  • Clone()の実装がキモ
    • 循環参照があったりするとやばい
    • Deep Copy
      • Save/Load処理があるのなら、それを使うと楽
  • オブジェクトを生成するにあたり、クローンそのままでよいこともあれば、パラメータを与えて初期化が必要なケースもある
    • 生成するオブジェクトによって必要なバラメータは当然異なるので、複製処理のインタフェースを統一することは難しい
    • ので、Clone()Initialize(...args) を呼ぶようにし、Clone()のインタフェースは統一する

関連するパターン

  • AbstractFactoryパターン
    • 競合するパターン
    • だが、AbstractFactoryをPrototypeパターンで実装することもできる
      • ConcreteFactoryを大量に作らなくてよくなる
  • CompositeパターンやDecoratorパターンを多用している場合、Prototypeパターン導入の恩恵が大きい