GoF本 FactoryMethod
まとめ
- オブジェクトを生成・返却するメソッドのインタフェースを定義する
- 実際にどのクラスを生成するかはサブクラスの実装|overrideに委ねる
別名
Virtual Constructor
モチベーション
- 世の中のプログラムフレームワークは抽象クラスを扱う
- フレームワーク利用者が具象クラスを定義して拡張できるようにしている
- フレームワークはどんな具象クラスが渡されるかわからないので、抽象クラス間の関係を管理する
- フレームワークは、管理対象のクラスのオブジェクトの生成を担うこともある
- でも抽象クラスだから直接はインスタンシエートできない
- フレームワークは「いつ」オブジェクトを生成すべきかを知っている
- 「どの種類の」クラスのオブジェクトを生成すべきかはわからない → 分離してクライアントコードに委ねる
つかいどころ
- Creatorは生成対象の具体的なクラスを知らない
- ので、派生ConcreteCreatorに生成対象のクラスを特定してもらう
- Strategyパターンのように、生成対象が仕事を別のクラス(helper subclasses)に委譲している場合、どのhelper subclassと組み合わせて使うかの知識を一ヶ所にまとめたい
登場人物
- Product
- 生成するオブジェクトのインタフェースを定義
- ConcreteProduct
- Productの派生
- Productに汎化できる程度には似通っている必要がある
- BuilderパターンにおけるProductは汎化しない。複雑で共通項が少なすぎるから
- Creator
- ファクトリメソッドを定義する
CreateProduct() : Product
とかそんなかんじCreateAndSetupProduct() : Product
の中で呼び出したりする(TemplateMethodパターン)
- ファクトリメソッドを定義する
- ConcreteCreator
- Creatorの派生
- ファクトリメソッドを実装する
功罪
- Product派生のいかなるConcreteProductクラスでもインスタンシエートできる
- ConcreteProductの数だけConcreteCreatorクラスを定義しないといけない
- オブジェクト生成処理の前後等にhookをもうけることができる
- デフォルトなにもしない
- 生成したらダイアログを出すようoverrideする、とかできる
- 並列な継承木を結びつける
実装
2種類に大別できる
- Creatorクラスは抽象クラス、ファクトリメソッドは抽象メソッド
- 基本のき
- Creatorクラスは具象クラス、ファクトリメソッドは実装をもつ
- たとえば、Productは具象クラスで、Strategyに処理を委譲している場合
Creator
のファクトリメソッドではProduct
の生成と、デフォルトのNullStrategy
の設定のみ行うConcreteCreator
のファクトリメソッドのoverrideの中では、基底のファクトリメソッドを呼び出し、StrategyをConcreteStrategy
にすげ替える
ConcreteCreator増えすぎ問題に対処するバリアント
Creatorを具象クラスにして、下記を適用する
- ファクトリメソッドに引数を追加
どのProductを作るかをenumとかで指定する - 作るべきProductクラスをCreatorのメンバ変数に格納する
- クラスが第一級オブジェクトである言語限定
- JSとか
- クラスが第一級オブジェクトである言語限定
- ジェネリクス使う
用例
あらゆるフレームワーク
関連するパターン
- AbstractFactoryパターン
- FactoryMethodパターンで実装されることがある
- 他の実装としては、Prototypeパターン等
- TemplateMethodパターン
- 「基底では中身のないファクトリメソッドを呼び出し、派生でファクトリメソッドの実装を書く」というのは、TemplateMethodそのもの