251

Strategy デザイン パターンと State デザイン パターンの違いは何ですか? 私はウェブ上でかなりの数の記事を読んでいましたが、違いを明確に理解できませんでした.

誰かが素人の用語の違いを説明できますか?

4

21 に答える 21

153

正直なところ、2 つのパターンは実際には非常に似ており、両者の決定的な違いは質問者によって異なる傾向があります。いくつかの一般的な選択肢は次のとおりです。

  • 状態は、それらを含むコンテキスト オブジェクトへの参照を格納します。戦略はそうではありません。
  • 状態はそれ自体を置き換えることができます (IE: コンテキスト オブジェクトの状態を別のものに変更する) が、戦略はできません。
  • 戦略はパラメータとしてコンテキスト オブジェクトに渡されますが、状態はコンテキスト オブジェクト自体によって作成されます。
  • 戦略は単一の特定のタスクのみを処理しますが、状態はコンテキスト オブジェクトが行うすべて (またはほとんどすべて) の基礎となる実装を提供します。

「クラシック」な実装は、リストのすべての項目について State または Strategy のいずれかに一致しますが、両方が混在するハイブリッドに出くわします。特定のものがより国家的であるか戦略的であるかは、最終的には主観的な問題です。

于 2012-10-12T23:10:10.557 に答える
129
  • 戦略パターンとは、実際には、(基本的に)同じことを実現する別の実装を用意することです。これにより、戦略の必要に応じて、一方の実装をもう一方の実装に置き換えることができます。たとえば、戦略パターンにさまざまな並べ替えアルゴリズムがあるとします。オブジェクトへの呼び出し元は、採用されている戦略に基づいて変更されませんが、戦略に関係なく、目標は同じです(コレクションを並べ替えます)。
  • 状態パターンは、状態に基づいてさまざまなことを行うことであり、呼び出し元はすべての可能な状態に対応する負担から解放されます。したがって、たとえば getStatus()、オブジェクトの状態に基づいて異なるステータスを返すメソッドがある場合でも、メソッドの呼び出し元は、潜在的な状態ごとに異なる方法でコーディングする必要はありません。
于 2009-11-01T20:32:20.160 に答える
94

違いは、単に異なる問題を解決するという点にあります。

  • Stateパターンは、オブジェクトの状態 (状態または型) を扱います。これは、状態に依存する動作をカプセル化します。
  • ストラテジーパターンは、オブジェクトが特定のタスクを実行する方法を扱い、アルゴリズムをカプセル化します

ただし、これらの異なる目標を達成するための構造は非常に似ています。どちらのパターンも、委譲を伴う構成の例です。


それらの利点に関するいくつかの観察:

Stateパターンを使用することにより、状態保持 (コンテキスト) クラスは、それがどのような状態または型であるか、およびどのような状態または型が使用可能であるかを知る必要がなくなります。これは、クラスがオープン/クローズド設計原則 (OCP) に準拠していることを意味します。クラスは、存在する状態/型の変更に対して閉じられていますが、状態/型は拡張に対して開かれています。

戦略パターンを使用することにより、アルゴリズムを使用する (コンテキスト) クラスは、特定のタスク (「アルゴリズム」) を実行する方法の知識から解放されます。このケースでは、OCP への準拠も作成されます。クラスは、このタスクを実行する方法に関する変更に対してクローズされていますが、設計は、このタスクを解決するための他のアルゴリズムの追加に対して非常にオープンです。
これにより、コンテキスト クラスの単一責任原則 (SRP) への準拠も向上する可能性があります。さらに、アルゴリズムは他のクラスで簡単に再利用できるようになります。

于 2012-07-16T12:44:10.957 に答える
55

誰かが素人の言葉で説明できますか?

設計パターンは、実際には「素人」の概念ではありませんが、できるだけ明確にするように努めます。どのような設計パターンも 3 次元で考えることができます。

  1. パターンが解決する問題。
  2. パターンの静的構造 (クラス図)。
  3. パターンのダイナミクス (シーケンス図)。

State と Strategy を比較してみましょう。

パターンが解決する問題

状態は 2 つのケースのいずれかで使用されます [GoF 本 p. 306] :

  • オブジェクトの動作はその状態に依存し、その状態に応じて実行時に動作を変更する必要があります。
  • 操作には、オブジェクトの状態に依存する大規模なマルチパート条件文があります。この状態は、通常、1 つ以上の列挙された定数によって表されます。多くの場合、複数の操作にこの同じ条件付き構造が含まれます。State パターンは、条件の各分岐を個別のクラスに配置します。これにより、オブジェクトの状態を、他のオブジェクトとは独立して変化できる独自のオブジェクトとして扱うことができます。

State パターンが解決する問題が実際にあることを確認したい場合は、有限ステート マシンを使用してオブジェクトの状態をモデル化できる必要があります。適用例はこちらでご覧いただけます

各状態遷移は State インターフェイスのメソッドです。これは、設計の場合、このパターンを適用する前に、状態遷移についてかなり確信を持っている必要があることを意味します。それ以外の場合、トランジションを追加または削除すると、インターフェイスとそれを実装するすべてのクラスを変更する必要があります。

私は個人的に、このパターンがそれほど役立つとは思いませんでした。ルックアップ テーブルを使用して有限ステート マシンをいつでも実装できます (オブジェクト指向の方法ではありませんが、かなりうまく機能します)。

攻略法は以下の【GoF本p. 316] :

  • 関連するクラスの多くは、動作のみが異なります。戦略は、多くの動作の 1 つを使用してクラスを構成する方法を提供します。
  • アルゴリズムのさまざまなバリアントが必要です。たとえば、さまざまな空間/時間のトレードオフを反映するアルゴリズムを定義できます。これらのバリアントがアルゴリズムのクラス階層として実装されている場合、戦略を使用できます [HO87]。
  • アルゴリズムは、クライアントが知る必要のないデータを使用します。戦略パターンを使用して、複雑なアルゴリズム固有のデータ構造を公開しないようにします。
  • クラスは多くの動作を定義し、これらはその操作で複数の条件ステートメントとして表示されます。多くの条件分岐の代わりに、関連する条件分岐を独自の Strategy クラスに移動します。

Strategy をどこに適用するかの最後のケースは、 Replace conditional with polymorphismとして知られるリファクタリングに関連しています。

概要:状態と戦略は、まったく異なる問題を解決します。問題が有限状態マシンでモデル化できない場合、状態パターンは適切ではない可能性があります。問題が複雑なアルゴリズムのバリアントをカプセル化することではない場合、戦略は適用されません。

パターンの静的構造

Stateには、次の UML クラス構造があります。

State PatternのPlantUMLクラス図

Strategyには、次の UML クラス構造があります。

Strategy PatternのPlantUMLクラス図

要約:静的構造に関しては、これら 2 つのパターンはほとんど同じです。実際、このようなパターン検出ツールは、「 [...] パターンの構造は同一であり、自動プロセスによるそれらの区別を禁止している (例えば、概念情報を参照することなく)」と見なします。

ただし、ConcreteStates が自身で状態遷移を決定する場合は、大きな違いが生じる可能性があります (上の図の「決定する可能性がある」関連付けを参照してください)。これにより、具体的な状態が結合されます。たとえば (次のセクションを参照)、状態 A は状態 B への遷移を決定します。 Context クラスが次の具体的な状態への遷移を決定すると、これらの依存関係はなくなります。

パターンのダイナミクス

上記の問題セクションで述べたように、Stateは、オブジェクトの状態に応じて実行時に動作が変化することを意味します。したがって、有限状態マシンの関係で説明したように、状態遷移の概念が適用されます。[GoF] は、遷移は ConcreteState サブクラス、または中央の場所 (テーブルベースの場所など) で定義できると述べています。

単純な有限状態マシンを想定してみましょう:

2 つの状態と 1 つの遷移を含む PlantUML 状態遷移図

サブクラスが (次の状態オブジェクトを返すことによって) 状態遷移を決定すると仮定すると、動的は次のようになります。

状態遷移の PlantUML シーケンス図

Strategyのダイナミクスを示すには、実際の例を借りると便利です。

戦略遷移の PlantUML シーケンス図

概要: 各パターンは、多態的な呼び出しを使用して、コンテキストに応じて何かを行います。State パターンでは、ポリモーフィックな呼び出し (遷移) によって次の状態が変化することがよくあります。戦略パターンでは、ポリモーフィック呼び出しは通常、コンテキストを変更しません (たとえば、一度クレジット カードで支払っても、次回は PayPal で支払うことを意味するわけではありません)。繰り返しになりますが、状態パターンのダイナミクスは、対応する有限状態マシンによって決定されます。これは、 (私にとって) このパターンを正しく適用するために不可欠です。

于 2015-05-24T14:18:33.180 に答える
26

戦略パターンには、アルゴリズムの実装をホスティングクラスから移動し、それを別のクラスに配置することが含まれます。これは、ホストクラスが各アルゴリズム自体の実装を提供する必要がないことを意味します。これにより、コードがクリーンでなくなる可能性があります。

並べ替えアルゴリズムは、すべて同じ種類のこと(並べ替え)を行うため、通常は例として使用されます。それぞれの異なる並べ替えアルゴリズムが独自のクラスに入れられている場合、クライアントは使用するアルゴリズムを簡単に選択でき、パターンはそれにアクセスする簡単な方法を提供します。

状態パターンには、オブジェクトの状態が変化したときにオブジェクトの動作を変更することが含まれます。これは、ホストクラスが、ある可能性のあるすべての異なる状態の動作の実装を提供していないことを意味します。ホストクラスは通常、特定の状態で必要な機能を提供するクラスをカプセル化し、別のクラスに切り替えます。状態が変化したとき。

于 2009-11-01T21:20:01.890 に答える
23

顧客からの電話を処理する IVR (Interactive Voice Response) システムを考えてみましょう。次の顧客を処理するようにプログラムすることができます。

  • 勤務日
  • 休日

この状況に対処するには、State Patternを使用できます。

  • 休日: IVR は、「電話は営業日の午前 9 時から午後 5 時までしか受けられません」と答えるだけです。
  • 営業日: 顧客をカスタマー ケア エグゼクティブに接続することで対応します。

顧客をサポート エグゼクティブに接続するこのプロセス自体は、次のいずれかに基づいてエグゼクティブが選択される戦略パターンを使用して実装できます。

  • ラウンドロビン
  • 最近使用されていないもの
  • その他の優先度ベースのアルゴリズム

戦略パターンはアクションを実行する「方法」を決定し、状態パターンはそれらを実行する「タイミング」を決定します。

于 2013-04-17T11:06:29.343 に答える
15

ストラテジーは、開始結果と終了結果が同じで、内部的に異なる方法を使用して、何かを「実行」するオブジェクトを表します。その意味で、それらは動詞の実装を表すことに類似しています。状態パターンOTOHは、何か「何か」であるオブジェクト、つまり操作の状態を使用します。それらはそのデータに対する操作を表すこともできますが、動詞よりも名詞の表現に類似しており、ステートマシンに合わせて調整されています。

于 2009-11-01T20:18:47.927 に答える
12

戦略パターンは、特定のタスクに複数のアルゴリズムがあり、クライアントが実行時に使用する実際の実装を決定する場合に使用されます。

Wiki戦略パターン記事の UML ダイアグラム:

ここに画像の説明を入力

主な機能:

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

詳細と実際の例については、この投稿を参照してください。

戦略パターンの実例

状態パターンにより、オブジェクトの内部状態が変化したときにオブジェクトの動作を変更できます

ウィキの状態パターン記事の UML ダイアグラム :

ここに画像の説明を入力

状態に基づいてオブジェクトの動作を変更する必要がある場合は、オブジェクトに状態変数を設定し、if-else 条件ブロックを使用して、状態に基づいてさまざまなアクションを実行できます。状態パターンは、コンテキスト状態の実装を通じてこれを達成するための体系的で疎結合の方法を提供するために使用されます。

詳細については、このジャーナル開発記事を参照してください。

ソース作成およびジャーナル開発記事との主な違い:

  1. StateStrategyの違いは拘束時間にあります。Strategy はバインド ワンス パターンですが、State はより動的です。
  2. StateStrategyの違いは意図にあります。ストラテジーでは、アルゴリズムの選択はかなり安定しています。State を使用すると、「コンテキスト」オブジェクトの状態が変化すると、戦略オブジェクトの「パレット」から選択されます
  3. コンテキストにはインスタンス変数として状態が含まれ、実装が状態に依存する可能性のある複数のタスクが存在する可能性がありますが、戦略パターンでは戦略は引数としてメソッドに渡され、コンテキストオブジェクトにはそれを格納する変数がありません。
于 2016-05-25T12:41:13.890 に答える
12

戦略: 戦略は固定されており、通常はいくつかのステップで構成されています。(並べ替えは 1 つのステップのみを構成するため、このパターンの目的を理解するには原始的すぎるため、非常に悪い例です)。戦略の「メイン」ルーチンは、いくつかの抽象メソッドを呼び出しています。たとえば、「Enter Room Strategy」、「main-method」は goThroughDoor() で、次のようになります。openDoor(); enterRoom(); 順番(); closeDoor(); if (wasLocked()) lockDoor();

この一般的な「アルゴリズム」のサブクラスは、ロックされている可能性のあるドアを通ってある部屋から別の部屋に移動するためのアルゴリズムのステップを実装できます。

つまり、戦略をサブクラス化しても、基本的なアルゴリズムは変更されず、個々のステップのみが変更されます。

THAT ABOVE はテンプレート メソッド パターンです。次に、一緒に属するステップ (ロック解除/ロックおよび開閉) を独自の実装オブジェクトに入れ、それらに委譲します。たとえば、キー付きのロックとコード カード付きのロックは、2 種類のロックです。戦略から「ステップ」オブジェクトに委譲します。これで、戦略パターンができました。

状態パターンはまったく別のものです。

ラッピング オブジェクトとラップされたオブジェクトがあります。包まれたものが「状態」です。状態オブジェクトは、そのラッパーを介してのみアクセスされます。ラップされたオブジェクトをいつでも変更できるようになったため、ラッパーはその状態、さらには「クラス」またはタイプを変更したように見えます。

たとえば、ログオン サービスがあります。ユーザー名とパスワードを受け入れます。これには、logon(String userName, String passwdHash) という 1 つのメソッドしかありません。ログオンを受け入れるかどうかを自分で決定する代わりに、状態オブジェクトに決定を委譲します。その状態オブジェクトは通常、ユーザーとパスの組み合わせが有効かどうかを確認し、ログオンを実行します。しかし今では、「チェッカー」を、特権ユーザーのみがログオンできるようにするもの (メンテナンス時間中など) と、誰もログオンさせないものとを交換できます。つまり、「チェッカー」はシステムの「ログオン状態」を表します。

最も重要な違いは、戦略を選択したら、完了するまでそれを使い続けることです。つまり、その「メイン メソッド」を呼び出し、そのメソッドが実行されている限り、戦略を変更することはありません。OTOH は、システムの実行時の状態パターンの状況で、必要に応じて任意に状態を変更します。

于 2011-06-01T12:28:07.897 に答える
10

素人の言葉で言えば、

戦略パターンでは、状態がないか、すべてが同じ状態です。さまざまな医師が、同じ状態の同じ患者の同じ病気をさまざまな方法で治療するなど、タスクを実行するさまざまな方法があります。

状態パターンには主観的に、患者の現在の状態(例えば、高熱または低体温)のような状態があり、それに基づいて次の行動方針(薬の処方)が決定されます。依存関係を述べる(技術的には構成)。

両者のコード比較に基づいて技術的に理解しようとすると、両者は非常に似ているため、状況の主観性が失われる可能性があります。

于 2015-10-09T18:07:35.333 に答える
3

これはかなり古い質問ですが、それでも同じ答えを探していましたが、これが発見したものです。

State パターンについて、Medial Player の再生ボタンの例を考えてみましょう。再生すると、再生が開始され、再生中であることがコンテキストに認識されます。クライアントが再生操作を実行するたびに、プレーヤーの現在の状態を確認します。これで、クライアントはオブジェクトの状態がコンテキスト オブジェクトを介して再生中であることを認識し、状態オブジェクトの一時停止アクション メソッドを呼び出します。状態を認識するクライアントの部分と、アクションを実行する必要がある状態は自動化できます。

https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm

戦略パターンの場合、クラス図の配置は状態パターンと同じです。クライアントは、何らかの操作を行うためにこの配置に来ます。つまり、さまざまな状態の代わりに、パターンに対して実行する必要があるさまざまな分析など、さまざまなアルゴリズムがあります。ここで、クライアントは、何をしたいのか、そのアルゴリズム (ビジネス定義のカスタム アルゴリズム) をコンテキストに伝え、それを実行します。

https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm

どちらも開閉原理を実装しているため、開発者は状態パターンと新しいアルゴリズムに新しい状態を追加できます。

ただし、違いは、オブジェクトの状態に基づいてさまざまなロジックを実行するために使用される状態パターンです。そして、戦略の場合はロジックが異なります。

于 2016-10-14T09:17:36.847 に答える
3

どちらのパターンも、いくつかの派生を持つ基本クラスに委譲しますが、これらの派生クラスがコンテキスト クラスへの参照を保持しているのは State パターンだけです。

別の見方をすると、Strategy パターンは State パターンの単純なバージョンです。必要に応じて、サブパターン。派生状態がコンテキストへの参照を保持するかどうか (つまり、コンテキストでメソッドを呼び出す必要があるかどうか) に大きく依存します。

詳細については、Robert C Martin (および Micah Martin) が著書「Agile Principles, Patterns and Practices in C#」でこれに答えています。( http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258 )

于 2009-11-01T20:41:34.243 に答える
3

Strategy と State の両方のパターンは同じ構造を持っています。両方のパターンの UML クラス図を見ると、まったく同じように見えますが、意図はまったく異なります。状態設計パターンはオブジェクトの状態を定義および管理するために使用され、戦略パターンは交換可能なアルゴリズムのセットを定義するために使用され、クライアントがそれらのいずれかを選択できるようにします。したがって、戦略パターンはクライアント主導のパターンであり、オブジェクトはその状態自体を管理できます。

于 2013-08-27T11:02:41.153 に答える
2

違いについては、http://c2.com/cgi/wiki?StrategyPatternで説明されています。データを分析するための全体的なフレームワーク内でさまざまなアルゴリズムを選択できるようにするために、戦略パターンを使用しました。これにより、フレームワーク全体とそのロジックを変更することなく、アルゴリズムを追加できます。

典型的な例は、関数を最適化するためのフレームワークを持っていることです。フレームワークはデータとパラメータを設定します。戦略パターンを使用すると、フレームワークを変更せずに、sttepest降下、共役勾配、BFGSなどのアルゴリズムを選択できます。

于 2009-11-01T20:18:50.967 に答える