コア Java アプリケーションでStateパターンとStrategyパターンを 適切に使用するには、Java プログラマがそれらの違いを明確に理解することが重要です。State と Strategy の両方のパターンは同様の構造を持ち、どちらもSOLID 原則の「O」を表すオープン/クローズ原則に基づいていますが、意図はまったく異なります。 Java のStrategyパターンは、クライアントに実行の柔軟性を提供するために関連するアルゴリズムのセットをカプセル化するために使用されます。クライアントは、 を使用するクラスのコンテキストを変更せずに、実行時に任意のアルゴリズムを選択できます。戦略パターンの一般的な例としては、暗号化、圧縮、並べ替えなどのアルゴリズムを使用するコードの作成が挙げられます。一方、State パターンを使用すると、オブジェクトが異なる状態で異なる動作をすることができます。現実の世界ではオブジェクトには状態があり、状態が異なると動作が異なることが多いため、たとえば、自動販売機は 状態にある場合にのみ商品を販売し、コインを入れるまでは販売しません。これで、Strategy パターンと State パターンの違いが明確にわかります。これらは異なる意図です。State パターンはオブジェクトが状態を管理するのに役立ちますが、Strategy パターンはクライアントが異なる動作を選択できるようにします。それほど簡単ではないもう 1 つの違いは、誰が行動の変化を推進しているのかということです。Strategy パターンの場合、これはコンテキストにさまざまな戦略を提供するクライアントであり、State パターンの場合、遷移はコンテキストまたはオブジェクト自体の状態によって制御されます。さらに、State オブジェクトの状態変更を自分で管理する場合は、コンテキストへの参照が必要です。たとえば、自動販売機はコンテキストの現在の状態を変更するメソッドを呼び出すことができなければなりません。一方、Strategy オブジェクトにはコンテキストへの参照が含まれることはなく、クライアント自体が選択した Strategy をコンテキストに渡します。状態パターンと戦略パターンの違いは、Java パターンに関する面接でよく聞かれる質問の 1 つです。Java パターンに関するこの記事では、それについて詳しく見ていきます。Java の Strategy パターンと State パターンの類似点と相違点をいくつか調べて、これらのパターンの理解を深めていきます。
Strategy
hasCoin
setState()
状態パターンと戦略パターンの類似点
状態パターンと戦略パターンの UML 図を見ると、両方が互いに似ていることがわかります。State を使用して動作を変更するオブジェクトは -object と呼ばれContext
、同様に、Strategy を使用して動作を変更するオブジェクトはContext
-object と呼ばれます。クライアントはContext
-object と対話することに注意してください。State パターンの場合、コンテキストは現在のオブジェクトとして保持される State オブジェクトに呼び出しメソッドを委任します。Strategy パターンの場合、コンテキストは Strategy オブジェクトをパラメータとして使用するか、作成時に提供されます。オブジェクトのコンテキストの。 Java の状態パターンの UML 図 この状態パターンの UML 図は、Java でオブジェクト指向の自動販売機設計を作成する際の古典的な問題を示しています。自動販売機の状態がインターフェイスを使用して表現され、インターフェイスには特定の状態を表す実装が含まれていることがわかります。各状態には、コンテキスト内で呼び出されたアクションの結果として別の状態に遷移するためのオブジェクト コンテキストへの参照もあります。 Java の Strategy パターンの UML 図 この Strategy パターンの UML 図には、ある種の機能実装が含まれています。多くの並べ替えアルゴリズムがあるため、この設計パターンを使用すると、クライアントはオブジェクトを並べ替えるときにアルゴリズムを選択できます。実際、Java Collection フレームワークは、Collections.sort()
このパターンを使用して、 Java でオブジェクトを並べ替えるために使用されるメソッドを実装します。唯一の違いは、クライアントが並べ替えアルゴリズムを選択できるようにする代わりに、 Comparator または Comparable インターフェイスのインスタンスを Java に渡すことによって比較戦略を指定できることです。Java のこれら 2 つの主要な設計パターンの類似点をいくつか見てみましょう。
- 状態とストラテジーの両方のパターンを使用すると、それらを使用するオブジェクトのコンテキストに影響を与えることなく、新しい状態とストラテジーを簡単に追加できます。
- どちらもオープン/クローズ原則に従ってコードを維持します。つまり、設計は拡張にはオープンですが、変更にはクローズされます。状態パターンと戦略パターンの場合、オブジェクトのコンテキストは変更、新しい状態または新しい戦略の導入に対して閉じられています。あるいは、他の状態のコンテキストを変更する必要がなく、最小限の変更が必要です。
- オブジェクト コンテキストが State パターンのオブジェクトの初期化状態から始まるのと同様に、Java の Strategy パターンの場合、オブジェクト コンテキストにもデフォルトのストラテジがあります。
- State パターンはさまざまなオブジェクトの状態の形でさまざまな動作を表し、Strategy パターンはさまざまなオブジェクトの戦略の形でさまざまな動作を表します。
- Strategy と State の両方のパターンは、動作実装のサブクラスに依存します。各具象戦略は抽象戦略を拡張し、各状態は状態を表すために使用されるインターフェイスまたは抽象クラスのサブクラスです。
JavaのStrategyパターンとStateパターンの違い
これで、State パターンと Strategy パターンは構造的には似ていますが、その意図が異なることがわかりました。これらの設計パターンの主な違いをいくつか見てみましょう。- Strategy パターンは、関連するアルゴリズムのセットをカプセル化し、クライアントが実行時の構成や委任に関係なく交換可能な動作を使用できるようにします。一方、State パターンは、クラスが異なる状態で異なる動作を示すのに役立ちます。
- State パターンと Strategy パターンの次の違いは、State はオブジェクトの状態をカプセル化するのに対し、Strategy パターンはアルゴリズムまたは戦略をカプセル化することです。状態はオブジェクトに関連付けられているため、再利用することはできませんが、戦略やアルゴリズムをそのコンテキストから切り離すことで再利用できます。
- State パターンでは、個人状態には状態間の遷移を実装するためのコンテキストへの参照が含まれる場合がありますが、Strategy にはそれが使用されるコンテキストへの参照が含まれません。
- ストラテジの実装は、それを使用するオブジェクトにパラメータとして渡すことができます。たとえば、Collection.sort() はストラテジであるComparatorを受け取ります。一方、状態はオブジェクトのコンテキスト自体の一部であり、時間の経過とともにオブジェクトのコンテキストはある状態から別の状態に遷移します。
- ストラテジーとステートは両方ともオープン/クローズの原則に従いますが、各ストラテジーには個別のアルゴリズムが含まれており、異なるストラテジーは互いに独立しているため、ストラテジーも単一責任の原則に従います。ある戦略を変更しても、別の戦略を変更する必要はありません。
- Strategy パターンと State パターンのもう 1 つの理論的な違いは、作成者がオブジェクトの「どのように」部分 (たとえば、sort オブジェクトがデータを並べ替える「方法」) を定義するのに対し、State パターンは「何を」 と「いつ」を定義することです。オブジェクトの一部、たとえば、オブジェクトが特定の状態にあるときに何ができるか。
- 状態遷移の順序は、State パターンで明確に定義されていますが、Strategy パターンにはそのような要件はありません。クライアントは、自分が選択した戦略の実装を自由に選択できます。
- 戦略パターンの一般的な例としては、並べ替えアルゴリズム、暗号化アルゴリズム、圧縮アルゴリズムなどのアルゴリズムのカプセル化が挙げられます。コードでさまざまな種類の関連アルゴリズムを使用する必要がある場合は、Strategy パターンの使用を検討する必要があります。一方、State パターンの使用を認識するのは非常に簡単です。多くのネストされた条件文を使用せずに状態と状態遷移を管理する必要がある場合、State パターンは使用するのに適したパターンです。
- 最後になりますが、State パターンと Strategy パターンの最も重要な違いの 1 つは、Strategy への変更はクライアントによって実行されるのに対し、State への変更はコンテキストまたはオブジェクトの状態自体によって実行できることです。
GO TO FULL VERSION