タイトルが示すように、「ああ!ここでファクトリパターンを使用する必要があります!」という意味の頭のトリガーをいつオフにする必要がありますか?これらの瞬間は他の多くのデザインパターンで発生することがわかりますが、私は自分自身を止めてこのパターンについて考えることは決してありません。
6 に答える
次のようなコードを見つけた場合は、おそらくファクトリを使用する必要があります。
IFoo obj;
if ( someCondition ) {
obj = new RegularFoo();
} else if ( otherCondition ) {
obj = new SpecialFoo();
} else {
obj = new DefaultFoo();
}
ファクトリパターンは、メソッド内のオブジェクトのグループのインスタンス化をカプセル化する場合に最適です。
言い換えると、すべてが同じ基本クラスから継承するオブジェクトのグループがある場合、またはすべてが同じインターフェイスを実装している場合、ファクトリパターン(つまり、「パターン」)を使用するインスタンスになります。にとって)。
ファクトリパターンについて考える2つの特定のケースを考えることができます。
- コンストラクターにロジックが含まれている場合。
- どの型がインスタンス化されるかをアプリケーションに心配させたくない場合(たとえば、返される抽象基本クラスまたはインターフェースがあります)。
GoFからの引用:
ファクトリメソッドパターンを使用する場合
- クラスは、作成する必要のあるオブジェクトのクラスを予測できません
- クラスは、そのサブクラスが作成するオブジェクトを指定することを望んでいます
- クラスは、いくつかのヘルパーサブクラスの1つに責任を委任し、どのヘルパーサブクラスが委任であるかについての知識をローカライズする必要があります。
GoFの本を強くお勧めします。カバーする23のパターンのそれぞれの適用性に関するセクションがあります。
ファクトリメソッドまたはアブストラクトファクトリについて話しているのですか?
両方が解決する基本的な問題は、フレームワークコードが構築する正確なクラスをクライアントに指定させることです。たとえば、クライアントが実装できるインターフェイスを提供すると、コードには次のようなものが含まれます。
IMyInterface x = new ConcreteClass();
クライアントがそのコードにアクセスせずに作成された正確なクラスを変更する方法はありません。
ファクトリメソッドは、特定のインターフェイスの具体的なクラスを構築する仮想メソッドです。コードのクライアントは、そのメソッドをオーバーライドして、作成するクラスを選択するオブジェクトを提供できます。コードでは次のようになります。
IMyInterface x = factory.Create();
factory
クライアントによって渡され、Create()を含むインターフェイスを実装します-正確なクラスを決定できます。
関連オブジェクトの階層があり、ベースインターフェイスとのみ通信するコードを記述できる必要がある場合は、AbstractFactoryを使用する必要があります。抽象ファクトリには、各階層から特定の具象オブジェクトを作成する複数のファクトリメソッドが含まれています。
Gang ofFourのDesignPatternsの本では、部屋、壁、ドアのある迷路の例を示しています。クライアントコードは次のようになります。
IRoom r = mazeFactory.CreateRoom();
IWall nw = mazeFactory.CreateWall();
IWall sw = mazeFactory.CreateWall();
IWall ew = mazeFactory.CreateWall();
IWall ww = mazeFactory.CreateWall();
r.AddNorthWall(nw);
r.AddSouthWall(sw);
r.AddEastWall(ew);
r.AddWestWall(ww);
(等々)
正確なコンクリートの壁、部屋、ドアは、提供するインターフェイス(IMazeFactory)を実装するmazeFactoryの実装者が決定できます。
したがって、他の人が実装して提供することを期待するインターフェイスまたは抽象クラスを提供している場合、ファクトリは、必要なときにコードが具象クラスを構築する方法も提供する方法です。
工場はローカリゼーションでよく使用されます。ローカリゼーションでは、市場ごとに異なるレイアウト、プロンプト、ルック/フィールを備えた画面があります。screen Factoryを取得して、言語に基づいて画面を作成し、そのパラメーターに基づいて適切なサブクラスを作成します。