ホームページ  >  記事  >  Java  >  Java ステート マシンの実装方法

Java ステート マシンの実装方法

WBOY
WBOY転載
2023-05-14 11:40:062575ブラウズ

2 つの状態があるとします。

Java ステート マシンの実装方法

この状態遷移は非常に簡単です。java で実装してみましょう。

プログラムの構造は次のとおりです。

Java ステート マシンの実装方法

まずステータスの表現を紹介しましょう

public class StateTransaction {
 
    // 当前状态
    private StateEnum currentState;
    // 相对应动作
    private ActionEnum action;
    // 下一个状态
    private StateEnum nextState;
    // 相应事件
    private Event event;
 
    public StateTransaction() {
 
    }
 
    public StateEnum getCurrentState() {
        return currentState;
    }
 
    public ActionEnum getAction() {
        return action;
    }
 
    public StateEnum getNextState() {
        return nextState;
    }
 
    public Event getEvent() {
        return event;
    }
 
    // 链式初始化对象
    public StateTransaction source(StateEnum state) {
        currentState = state;
        return this;
    }
    public StateTransaction when(ActionEnum action) {
        this.action = action;
        return this;
    }
    public StateTransaction target(StateEnum state) {
        nextState = state;
        return this;
    }
    public StateTransaction how(Event event) {
        this.event = event;
        return this;
    }
 
}

ご覧のとおり、ステータスを表す 4 つの量があります。

    currentState: 現在の状態を示します
  • action: 対応するアクションを示します
  • nextState: 次の状態を示します
  • event: 対応するイベントを示します
  • この 4 つのタプルの意味は、currentState 状態にあるときにアクションが発生すると、 nextState ステータスに転送され、イベント イベントへの応答がトリガーされます。

チェーン初期化の 4 つのメソッドに注目してください。これら 4 つのメソッドの定義により、状態の初期化が非常にエレガントになります。

イベントを見てみましょう。イベントはインターフェイスです。他の特定のイベントは、特定の操作を実行するためにこのインターフェイスを実装します。私たちのプログラムは、複雑な操作を行わずにいくつかの情報を直接出力します

public interface Event {
 
    public String handle();
 
}
public class PlayBasketballEvent implements Event{
    @Override
    public String handle() {
        System.out.println("开始打篮球");
        return "开始打篮球";
    }
}
public class SingDanceRapEvent implements Event{
    @Override
    public String handle() {
        System.out.println("开始唱,跳,rap");
        return "开始唱,跳,rap";
    }
}

さらに、また、状態とアクションをそれぞれ表す 2 つの列挙型クラスを定義する必要もあります

public enum StateEnum {
    // 打篮球
    PLAY_BASKETBALL,
    // 唱跳rap
    SING_DANCE_RAP
}
public enum ActionEnum {
    // 音乐起
    MUSIC_ON,
    // 音乐结束
    MUSIC_OFF
}

上記の準備が完了したら、状態転送を実行するためのステート マシン クラスが必要です

public class StateMachine {
 
    // 存储状态信息
    private List<StateTransaction> stateTransactionList;
    // 记录当前状态
    private StateEnum currentState;
 
    public StateMachine(StateEnum state) {
        currentState = state;
        stateTransactionList = new ArrayList<>();
    }
 
    // 添加一条状态信息
    public StateTransaction addone() {
        StateTransaction stateTransaction = new StateTransaction();
        stateTransactionList.add(stateTransaction);
        return stateTransaction;
    }
 
    // 进行状态转移
    public StateTransaction execute(ActionEnum action) {
        for(int i=0; i<stateTransactionList.size(); i++) {
            if(currentState==stateTransactionList.get(i).getCurrentState() &&
                action==stateTransactionList.get(i).getAction()) {
                stateTransactionList.get(i).getEvent().handle();
                currentState = stateTransactionList.get(i).getNextState();
                return stateTransactionList.get(i);
            }
        }
        return null;
    }
 
}

主要なメソッドが 2 つあります上記のコード、つまり addone() とexecute()

最初に addone() について話しましょう。このメソッドは最初に StateTransaction オブジェクトを初期化し、次にそれを List に入れ、最後にこれを追加します。オブジェクトが返されます。このオブジェクトを取得したら、コンテンツを入力できます。

execute() について話しましょう。このメソッドは、ActionEnum をパラメータとして受け取り、リストを走査して、対応するアクションを通じて現在のステータスを変更することによって取得される次のオブジェクトのステータス情報を探します。見つかった場合はイベントを実行し、handle() メソッドを使用して現在の状態を転送し、最後に StateTransaction を返します。見つからない場合は null を返します。

最後に初期化メソッドを見てみましょう

public class StateMachineTest {
 
    public static void main(String[] args) {
        StateMachine machine = new StateMachine(StateEnum.PLAY_BASKETBALL);
        // 打篮球的时候,一旦音乐起,就会开始唱跳rap
        machine.addone().source(StateEnum.PLAY_BASKETBALL).when(ActionEnum.MUSIC_ON)
                .target(StateEnum.SING_DANCE_RAP).how(new SingDanceRapEvent());
        // 唱跳rap的时候,一旦音乐停止,就会开始打篮球
        machine.addone().source(StateEnum.SING_DANCE_RAP).when(ActionEnum.MUSIC_OFF)
                .target(StateEnum.PLAY_BASKETBALL).how(new PlayBasketballEvent());
        machine.execute(ActionEnum.MUSIC_ON);
        machine.execute(ActionEnum.MUSIC_OFF);
    }
 
}

ご覧のとおり、チェーン メソッドを使用して状態転送メッセージを直接作成できます。これは非常にエレガントです

プログラム出力は次のとおりです

以上がJava ステート マシンの実装方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。