web-dev-qa-db-ja.com

FactoryとStrategyパターンの違いは何ですか?

工場と戦略パターンの違いを説明できる人はいますか?

私にとっては、両方とも余分なファクトリクラス(ファクトリパターンで製品のオブジェクトを作成する)以外は同じように見えます

128
Sappidireddy

ファクトリパターンは、創造的なパターンです。戦略パターンは運用パターンです。別の言い方をすれば、特定のタイプのオブジェクトを作成するためにファクトリーパターンが使用されます。戦略パターンは、特定の方法で操作(または操作のセット)を実行するために使用されます。古典的な例では、工場はさまざまな種類の動物を作成する可能性があります:犬、猫、虎、戦略パターンは移動などの特定のアクションを実行します。 Run、Walk、またはLope戦略を使用します。

実際、この2つは一緒に使用できます。たとえば、ビジネスオブジェクトを作成するファクトリがあるとします。永続化メディアに基づいて異なる戦略を使用する場合があります。データがXMLでローカルに保存されている場合、1つの戦略を使用します。データが別のデータベースのリモートにある場合、別のデータベースを使用します。

191
tvanfosson

戦略パターンを使用すると、クラスの動作を多態的に変更できます。

ファクトリパターンを使用すると、オブジェクト作成をカプセル化できます。

ゲイリーは素晴らしい点を指摘しています。 「concretions」ではなく抽象化にコーディングの原則を使用している場合、パターンの多くはテーマのバリエーションのように見え始めます。

24
jlembke

Tvanfossonが言ったことに付け加えると、多くのパターンは実装に関しては同じように見えます。つまり、多くの場合、以前はコードに存在していなかったインターフェイスを作成し、そのインターフェイスの実装を作成する必要があります。違いは、その目的と使用方法にあります。

20
Gary Kephart
  • ファクトリー(メソッド)パターン。

具体的なインスタンスのみを作成します。引数が異なると、オブジェクトが異なる場合があります。ロジックなどに依存します。

  • 戦略パターン。

アルゴリズムをカプセル化して(ステップ)、アクションを実行します。そのため、戦略を変更して別のアルゴリズムを使用できます。

どちらも非常に似ているように見えますが、目的はかなり異なります。1つの目的はアクションを作成することです。

そう。 Factoryメソッドが修正されている場合、次のようになります。

 public Command getCommand( int operatingSystem ) { 
      switch( operatingSystem ) { 
           case UNIX    :
           case LINUX   : return new UnixCommand();
           case WINDOWS : return new WindowsCommand();
           case OSX     : return new OSXCommand();
       }
  }

しかし、工場がより高度な、または動的な作成を必要としていると仮定します。ファクトリメソッドに戦略を追加し、再コンパイルせずに変更できます。戦略は実行時に変更される場合があります。

10
OscarRyz

まず、単純ファクトリーと抽象ファクトリーの違いを作成する必要があります。最初のものは、オブジェクト作成のファクトリーとして機能するクラスを1つだけ持つ単純なファクトリーです。後者では、ファクトリーインターフェース(メソッド名を定義する)に接続し、このインターフェースを実装するさまざまなファクトリーを呼び出します。いくつかの基準に基づいて、同じメソッドの異なる実装を持つことになっています。たとえば、最初のWindowsButtonCreationFactory(Windowsのルックアンドフィールでボタンを作成)と2番目のLinuxButtonCreationFactory(Linuxのルックアンドフィールでボタンを作成)という2つのファクトリーによって実装されるButtonCreationFactoryインターフェースがあります。そのため、これらの両方の工場には、異なる実装(アルゴリズム)で同じ作成方法があります。必要なボタンのタイプに応じて、ランタイムでこれを参照できます。

たとえば、Linuxのルックアンドフィールのボタンが必要な場合:

ButtonCreationFactory myFactory = new LinuxButtonCreationFactory();
Button button1 = myFactory.createButton(...);

または、Windowsボタンが必要な場合

ButtonCreationFactory myFactory = new WindowsButtonCreationFactory();
Button button1 = myFactory.createButton(...);

まさにこの場合、何らかの作成のアルゴリズムを区別するため、一種の戦略パターンになります。ただし、動作アルゴリズムではなくOBJECT CREATIONに使用されるため、意味的には異なります。したがって、基本的に抽象ファクトリーでは、異なる戦略を使用してオブジェクトを作成するため、戦略パターンに非常に似ています。ただし、AbstractFactoryは創造的であり、Strategyパターンは動作可能です。実装に関しては、結果は同じになります。

9
interboy

Factory(およびFactoryによって返されるFactoryMethod)

  1. 創造パターン
  2. 継承に基づいて
  3. Factoryは、具象オブジェクトを返すFactoryメソッド(インターフェース)を返します
  4. インターフェイスの代わりに新しい具象オブジェクトを使用でき、クライアント(呼び出し元)はすべての具象実装を認識しないでください
  5. クライアントは常にインターフェイスのみにアクセスし、Factoryメソッドでオブジェクト作成の詳細を非表示にすることができます

これをご覧ください wikipedia article および javarevisited article

戦略パターン:

  1. それは行動パターンです
  2. 委任に基づいています
  3. メソッドの動作を変更することにより、オブジェクトの内臓を変更します
  4. アルゴリズムのファミリーを切り替えるために使用されます
  5. 実行時にオブジェクトの動作を変更します

例:

特定のアイテム(AirFareチケットまたはShoppingCartアイテム)の割引戦略を設定できます。この例では、7月から12月にかけてアイテムに25%の割引を提供し、1月から6月にかけてアイテムの割引を提供しません。

関連記事:

戦略パターンの実世界の例

デザインパターン:ファクトリーvsファクトリーメソッドvsアブストラクトファクトリー

8
Ravindra babu

簡単な用語での戦略パターンは、実装クラスに関係のない動作の実行時作成です。もう一方のファクトリには、具象クラスインスタンスの実行時作成があり、実装されたインターフェイスによって公開される動作(メソッド)を使用するのはユーザー次第です。

3
Gurum

オスカーの発言を拡張し、彼のコードを参照するには:

GetCommandはFactoryであり、UnixCommand、WindowsCommand、およびOSXCommandクラスは戦略です

2
Spechal

コードや分類を見るだけでは違いを理解できません。 GoFパターンを正しく把握するには、それらの意図を探します。

戦略:「アルゴリズムのファミリを定義し、各アルゴリズムをカプセル化し、それらを交換可能にします。戦略により、アルゴリズムはそれを使用するクライアントとは独立して変化できます。」

ファクトリメソッド:「オブジェクトを作成するためのインターフェイスを定義しますが、インスタンス化するクラスをサブクラスに決定させます。ファクトリメソッドにより、クラスはインスタンス化をサブクラスに延期できます。」

そして、これら2つのパターンの意図と違いについて詳しく説明します: ファクトリーメソッドと戦略デザインパターンの違い

1
user2920760

戦略と工場は異なる目的です。戦略では、アプローチを定義し、このパターンを使用して、動作(アルゴリズム)を交換できます。 Factoryに来ると、さまざまなバリエーションがあります。ただし、GO4の元のパターンでは、ファクトリはオブジェクトの作成を子クラスに任せています。ここで、工場では、目的の動作ではなく、完全なインスタンスを置き換えます。これにより、アルゴリズムではなく、完全なシステムを置き換えます。

1
Brainchild

Factory実装の彼の例がかなり密結合で非常に閉じているという点で、私はOscarから脱線するかもしれません。あなたの選択が戦略パターンであるのも不思議ではありません。 Factoryの実装は、インスタンス化される特定のクラスの固定数に依存するべきではありません。次に例を示します。

public Command getCommand( int operatingSystem ) {        
   return commandTable.get(operatingSystem); 
}

...

public class WindowsCommand implements Command {
    ...
    static {
        CommandTable.getInstance().registerCommand(WIN_COMMAND_ID, new WindowsCommand());
    }

}

どちらかを選択するための最も適切な基準は、クラスとメソッドに名前を付けるために使用する用語がほとんどであると思います。実行時に実行するコード。つまり、両方のパターンのいずれかを使用することで目標を達成できます。

1
Rick B.

ファクトリパターンは、指定されたプロパティ(動作)で作成される作成パターンです。一方、作成後の実行時には、プロパティを変更しないでください(動作)。異なるプロパティ(動作)が必要な場合、オブジェクトを削除し、必要なプロパティ(動作)を使用して新しいオブジェクトを作成する必要があります。それは意地悪ではありません。一方、戦略パターンuの場合、実行時にプロパティ(動作)を変更できます。

0
user1808932