FactoryとStrategyパターンの違いは何ですか?
-
03-07-2019 - |
質問
工場と戦略のパターンの違いを説明できる人はいますか?
私にとっては、余分なファクトリクラス(ファクトリパターンで製品のオブジェクトを作成する)以外は同じように見えます
解決
ファクトリパターンは、創造的なパターンです。戦略パターンは運用パターンです。別の言い方をすれば、特定のタイプのオブジェクトを作成するためにファクトリーパターンが使用されます。戦略パターンは、特定の方法で操作(または操作のセット)を実行するために使用されます。古典的な例では、工場はさまざまな種類の動物を作成する可能性があります:犬、猫、虎、一方、戦略パターンは特定のアクション(移動など)を実行します。 Run、Walk、またはLope戦略を使用します。
実際、この2つは一緒に使用できます。たとえば、ビジネスオブジェクトを作成するファクトリがあるとします。永続化メディアに基づいて異なる戦略を使用する場合があります。データがXMLでローカルに保存されている場合、1つの戦略を使用します。データが別のデータベースのリモートにある場合、別のデータベースを使用します。
他のヒント
戦略パターンを使用すると、クラスの動作を多態的に変更できます。
ファクトリパターンを使用すると、オブジェクト作成をカプセル化できます。
ゲイリーは重要なポイントです。 「concretions」ではなく抽象化にコーディングの原則を使用している場合、その後、多くのパターンがテーマのバリエーションのように見え始めます。
tvanfossonが言ったことに付け加えると、多くのパターンは実装に関しては同じように見えます。つまり、多くの場合、以前はコードに存在していなかったインターフェイスを作成し、そのインターフェイスの実装を作成する必要があります。違いは、その目的と使用方法にあります。
- ファクトリー(メソッド)パターン。
具体的なインスタンスのみを作成します。引数が異なると、オブジェクトが異なる場合があります。ロジックなどに依存します。
- 戦略パターン。
アルゴリズムをカプセル化して(ステップ)、アクションを実行します。そのため、戦略を変更して別のアルゴリズムを使用できます。
どちらも非常によく似ていますが、目的はかなり異なりますが、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();
}
}
しかし、より高度な、または動的な作成が必要なファクトリーがあるとします。ファクトリメソッドに戦略を追加し、再コンパイルせずに変更できます。戦略は実行時に変更される場合があります。
まず、単純ファクトリーと抽象ファクトリーの違いを作成する必要があります。最初のものは、オブジェクト作成のファクトリとして機能するクラスを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パターンは動作可能です。実装に関しては、結果は同じになります。
Factory(およびFactoryによって返されるFactoryMethod):
- 作成パターン
- 継承に基づく
- Factoryは、具象オブジェクトを返すファクトリメソッド(インターフェイス)を返します
- インターフェイスの代わりに新しい具象オブジェクトを使用でき、クライアント(呼び出し元)はすべての具象実装を認識しないでください
- クライアントは常にインターフェイスのみにアクセスし、Factoryメソッドでオブジェクト作成の詳細を非表示にできます
この wikipediaの記事および javarevisitedの記事
戦略パターン:
- これは行動パターンです
- 委任に基づいています
- メソッドの動作を変更することにより、オブジェクトの内臓を変更します
- アルゴリズムのファミリーを切り替えるために使用されます
- 実行時にオブジェクトの動作を変更します
例:
特定のアイテム(AirFareチケットまたはShoppingCartアイテム)の割引戦略を設定できます。この例では、7月から12月までは25%の割引を提供し、1月から6月までは25%の割引を提供します。
関連記事:
単純な用語での戦略パターンは、実装クラスに関係のない動作の実行時作成です。もう一方のファクトリには、具象クラスインスタンスの実行時作成があり、実装されたインターフェイスによって公開される動作(メソッド)を使用するのはユーザー次第です。
オスカーの発言を拡張し、彼のコードを参照する:
getCommandはファクトリーであり、UnixCommand、WindowsCommand、およびOSXCommandクラスは戦略です
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());
}
}
いずれかを選択するための最も適切な基準は、ほとんどの場合、クラスではなくインターフェイスにプログラムし、目標にも焦点を当てる必要があることを考慮して、クラスとメソッドに名前を付けるために使用する用語です。実行時に実行するコードを決定することを目的としています。つまり、両方のパターンのいずれかを使用することで目標を達成できます。
戦略とファクトリーは異なる目的です。戦略では、アプローチを定義し、このパターンを使用して、動作(アルゴリズム)を交換できます。 Factoryに来ると、さまざまなバリエーションがあります。ただし、GO4の元のパターンでは、ファクトリはオブジェクトの作成を子クラスに任せています。ここで、工場では、目的の動作ではなく、完全なインスタンスを置き換えます。これにより、アルゴリズムではなく、完全なシステムを置き換えます。
コードまたはカテゴリを見るだけでは違いを理解できません。 GoFパターンを正しく把握するには、それらの意図を探します:
戦略:"一連のアルゴリズムを定義し、各アルゴリズムをカプセル化し、それらを交換可能にします。戦略により、アルゴリズムを使用するクライアントとは独立してアルゴリズムを変更できます。"
Factory Method:"オブジェクトを作成するためのインターフェースを定義しますが、インスタンス化するクラスをサブクラスに決定させます。ファクトリメソッドにより、クラスはインスタンス化をサブクラスに延期できます。"
そして、これら2つのパターンの意図と違いについて詳しく説明します:ファクトリメソッドと戦略の設計パターンの違い
ファクトリーパターンは、指定されたプロパティ(動作)で作成される作成パターンです。一方、作成後の実行時には、プロパティ(動作)を変更しません。したがって、異なるプロパティ(動作)が必要な場合は、オブジェクトを削除し、必要なプロパティ(動作)を使用して新しいオブジェクトを作成する必要があります。それは意地悪ではありません。 一方、戦略パターンuの場合、実行時にプロパティ(動作)を変更できます。