ステートモード


状態パターンでは、クラスの動作はその状態に基づいて変化します。このタイプの設計パターンは動作パターンです。

状態パターンでは、さまざまな状態を表すオブジェクトと、状態オブジェクトの変化に応じて動作が変化するコンテキスト オブジェクトを作成します。

はじめに

目的: 内部状態が変化したときにオブジェクトの動作を変更できるようにし、オブジェクトがそのクラスが変更されたかのように見えるようにします。

主な解決策: オブジェクトの動作はその状態 (プロパティ) に依存し、その状態の変化に応じて関連する動作を変更できます。

いつ使用するか: コードには、オブジェクトの状態に関連する多数の条件文が含まれています。

解決方法: さまざまな特定のステータスクラスを抽象化します。

キーコード: 通常、コマンドモードインターフェースにはメソッドが 1 つだけあります。状態パターン インターフェイスには 1 つ以上のメソッドがあります。また、状態パターンの実装クラスのメソッドは、通常、値を返したり、インスタンス変数の値を変更したりする。言い換えれば、状態パターンは一般にオブジェクトの状態に関連しています。実装クラスのメソッドにはさまざまな機能があり、インターフェイス内のメソッドをオーバーライドします。コマンド モードと同様に、ステート モードを使用して、if...else などの条件付き選択ステートメントを削除することもできます。

応用例: 1. バスケットボールをしているとき、アスリートは正常な状態、異常な状態、超常的な状態を持つ可能性があります。 2. Zeng Hou Yi のチャイムでは、「ベルは抽象的なインターフェイス」、「Zhong A」などは具体的な状態、「Zeng Hou Yi のチャイム」は特定の環境 (コンテキスト) です。

利点: 1. 変換ルールをカプセル化します。 2. 考えられる状態を列挙します。状態を列挙する前に、状態のタイプを決定する必要があります。 3. 特定の状態に関連するすべての動作をクラスに入れると、オブジェクトの動作を変更するためにオブジェクトの状態を変更するだけで、新しい状態を簡単に追加できます。 4. 状態遷移ロジックを、巨大な条件文ブロックの代わりに状態オブジェクトと統合できるようにします。 5. 複数の環境オブジェクトが状態オブジェクトを共有できるため、システム内のオブジェクトの数が減ります。

欠点: 1. 状態モードを使用すると、システム クラスとオブジェクトの数が必然的に増加します。 2. ステート モードの構造と実装は比較的複雑です。不適切に使用すると、プログラムの構造とコードが混乱する可能性があります。 3. 状態モードは、状態を切り替えることができる「開始および終了原理」をあまりサポートしていません。新しい状態クラスを追加するには、状態変換を担当するソース コードを変更する必要があります。そうしないと、新しい状態クラスに切り替えることができません。状態と変更 特定の状態クラスの動作には、対応するクラスのソース コードの変更も必要です。

使用シナリオ: 1. 状態の変化に応じて動作が変化するシナリオ。 2. 条件文と分岐文の置き換え。

注: 動作が状態によって制限されており、状態が 5 つ以下である場合は、状態パターンを使用します。

実装

Stateインターフェースと、Stateインターフェースを実装するエンティティ状態クラスを作成します。 Context は、何らかの状態を持つクラスです。

StatePatternDemo、私たちのデモクラスはContextと状態オブジェクトを使用して、状態が変化したときのContextの動作の変化を示します。

state_pattern_uml_diagram.jpg

ステップ 1

インターフェースを作成します。

State.java

public interface State {
   public void doAction(Context context);
}

ステップ 2

インターフェースを実装するエンティティクラスを作成します。

StartState.java

public class StartState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);	
   }

   public String toString(){
      return "Start State";
   }
}

StopState.java

public class StopState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      context.setState(this);	
   }

   public String toString(){
      return "Stop State";
   }
}

ステップ 3

Contextクラスを作成します。

Context.java

public class Context {
   private State state;

   public Context(){
      state = null;
   }

   public void setState(State state){
      this.state = state;		
   }

   public State getState(){
      return state;
   }
}

ステップ 4

Contextを使用して、状態Stateが変化したときの動作の変化を確認します。

StatePatternDemo.java

public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();

      StartState startState = new StartState();
      startState.doAction(context);

      System.out.println(context.getState().toString());

      StopState stopState = new StopState();
      stopState.doAction(context);

      System.out.println(context.getState().toString());
   }
}

ステップ 5

出力を確認します。

りー