23種類の設計モード(22)java状態モード


一、概要
システム内のあるオブジェクトが複数の状態にある場合には、これらの状態の間で変換することができ、オブジェクトが異なる状態で動作する場合には状態モードを使用することができます。状態モードは、オブジェクトの状態をそのオブジェクトから分離し、専用の状態クラスにカプセル化し、オブジェクトの状態を柔軟に変化させる。状態モードは、対象行動型のモードです。
二、適用シーン
システム中の複雑なオブジェクトの様々な状態遷移と異なる状態での挙動の実装問題を解決するために使用されます。簡単に言えば、処理対象の複数の状態とその相互変換です。
三、UML類図

四、参加者
1)、AbstractState(抽象状態類):
        抽象的な状態クラスでは、異なる状態での行動抽象的な方法を定義し、サブクラス(異なる状態のサブクラス)で異なる行動操作を実現します。
2)、Concrete State(具体的な状態での行動を実現する状態サブクラス):
        抽象的な状態のサブクラスは、それぞれのサブクラスが環境(Conteext)の一つの状態に関連する行為を実現し、それぞれの具体的な状態種類が環境の具体的な状態に対応しています。
3)、Conteext(状態対象を持つ環境類):
        状態属性を持ち、環境の多様性により、異なる状態を持つことができ、また異なる状態での行動も異なります。環境クラスで抽象的な状態例を維持し、この例は現在の環境の状態を定義し、具体的な状態挙動を分離して、異なる状態サブクラスによって完成させる。
五、用例学習
1、抽象的な状態:Stare.java

/** 
* JAVA           
*       
* @author [email protected] 
* 
*/ 
public abstract class State { 
  /** 
  *         ,                   
  */ 
  public abstract void Behavior(); 
 
}
2、具体的な状態のサブクラスA:Cocrete StarteA.java

/** 
*        A 
* @author [email protected] 
*/ 
public class ConcreteStateA extends State { 
 
  @Override 
  public void Behavior() { 
    //   A      ,         ,      
    //  :           ,         
    System.out.println("           ,        "); 
  } 
 
}
3、具体的な状態のサブクラスB:Cocrete StteB.java

/** 
*        B 
* @author [email protected] 
* 
*/ 
public class ConcreteStateB extends State { 
 
  @Override 
  public void Behavior() { 
    //   B      ,         ,     
    //  :          ,         
    System.out.println("          ,       "); 
  } 
 
}
4、状態の対象を持つ環境類:Contect.java

/** 
*   /    <br/> 
*       ,            [     /          ] 
* @author [email protected] 
* 
*/ 
public class Context { 
  //               
  private State state; 
   
  /* 
  *          <br/> 
  *       : 
  * 1>、  bill >= 0.00$ :              
  * 2>、  bill < 0.00$ :              
  */ 
  private double bill; 
   
  /** 
  *       ,               <br/> 
  *                           
  */ 
  public void Handle(){ 
    checkState(); 
    state.Behavior(); 
  } 
   
   
  /** 
  *       :     /           
  */ 
  private void checkState(){ 
    if(bill >= 0.00){ 
      setState(new ConcreteStateA()); 
    } else { 
      setState(new ConcreteStateB()); 
    } 
  } 
   
   
  /** 
  *       <br/> 
  *     ,                    /  ,                 
  * @param state 
  */ 
  private void setState(State state){ 
    this.state = state; 
  } 
 
 
  public double getBill() { 
    return bill; 
  } 
 
  public void setBill(double bill) { 
    this.bill = bill; 
  } 
}
5、テストクライアントの呼び出しクラス:Cient.java

public class Client { 
 
  public static void main(String[] args) { 
    Context context = new Context(); 
    context.setBill(5.50); 
    System.out.println("      :" + context.getBill() + "$"); 
    context.Handle(); 
     
    context.setBill(-1.50); 
    System.out.println("      :" + context.getBill() + "$"); 
    context.Handle(); 
     
    context.setBill(50.00); 
    System.out.println("      :" + context.getBill() + "$"); 
    context.Handle(); 
  } 
}
6、プログラム運転結果:
現在の通話料の残高:5.5$ 
携帯は未充電で停止しています。正常に電話がかけられます。 
現在の通話料の残高:-1.5$ 
携帯は有料で停止していますので、電話はできません。 
現在の通話料の残高:50.0$ 
携帯は未充電で停止しています。正常に電話がかけられます。
六、拡張 
状態モードでは状態の切り替えについて2つの異なる実現方法があります。
方式一:状態の変化/切り替え  環境クラスで実現します。  上のような用例コードContect類のcheckState()方法です。

/** 
  *       :     /           
  */ 
  private void checkState(){ 
    if(bill >= 0.00){ 
      setState(new ConcreteStateA()); 
    } else { 
      setState(new ConcreteStateB()); 
    } 
  }
方式二:状態の変化/切り替え  具体的な状態でサブクラスで実現します。
実装手順は以下の通りです。
1)環境系Contectクラスでは、一つのステータスインスタンスオブジェクトを初期化し、環境Contectオブジェクトをサブクラス状態の構造パラメータとして具体的な状態サブクラスの例に渡す。
Conttext.java類の中で

//        
this.state = new ConcreteStateA(this);
2)具体的なサブクラスの状態類において、構造的に入ってくるcontextオブジェクトに基づいて、contextオブジェクトの属性値を呼び出して、トラフィックロジック判定を行い、状態のチェックと切り替えを行う。
具体的な状態では、サブクラスのCocrete StarteA.javaクラス:

/** 
*        A 
* @author [email protected] 
*/ 
public class ConcreteStateA extends State { 
  private Context ctx; 
   
  public ConcreteStateA(Context context){ 
    ctx = context; 
  } 
   
  @Override 
  public void Behavior() { 
    //   A      ,         ,      
    //  :           ,         
    System.out.println("           ,        "); 
    checkState(); 
     
  } 
 
  /** 
  *                 <br/> 
  *                 
  */ 
  private void checkState(){ 
    if (ctx.getBill() < 0.00) { 
      ctx.setState(new ConcreteStateB(ctx)); 
    } 
  } 
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。