溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java狀態(tài)機(jī)怎么實(shí)現(xiàn)

發(fā)布時(shí)間:2023-05-06 10:50:19 來源:億速云 閱讀:158 作者:zzz 欄目:開發(fā)技術(shù)

今天小編給大家分享一下Java狀態(tài)機(jī)怎么實(shí)現(xiàn)的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

假設(shè)我們有兩個(gè)狀態(tài)

Java狀態(tài)機(jī)怎么實(shí)現(xiàn)

這個(gè)狀態(tài)轉(zhuǎn)換非常簡單,我們來試著用java實(shí)現(xiàn)一下

程序結(jié)構(gòu)如下圖

Java狀態(tài)機(jī)怎么實(shí)現(xiàn)

我們先來介紹一下狀態(tài)的表示

public class StateTransaction {
 
    // 當(dāng)前狀態(tài)
    private StateEnum currentState;
    // 相對(duì)應(yīng)動(dòng)作
    private ActionEnum action;
    // 下一個(gè)狀態(tài)
    private StateEnum nextState;
    // 相應(yīng)事件
    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;
    }
 
    // 鏈?zhǔn)匠跏蓟瘜?duì)象
    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;
    }
 
}

可以看到,表示狀態(tài)的量一共有四個(gè),分別是:

  • currentState:表示當(dāng)前狀態(tài)

  • action:表示相應(yīng)動(dòng)作

  • nextState:表示下一個(gè)狀態(tài)

  • event:表示相應(yīng)事件

這個(gè)四元組的含義就是,當(dāng)處于currentState狀態(tài)的時(shí)候,如果發(fā)生了action動(dòng)作,就會(huì)轉(zhuǎn)移到nextState狀態(tài),并且會(huì)觸發(fā)event事件的響應(yīng)。

注意看鏈?zhǔn)匠跏蓟乃膫€(gè)方法,這四個(gè)方法的定義讓狀態(tài)的初始化變得很優(yōu)雅。

接著來看一下事件,Event是一個(gè)接口,其他具體的事件實(shí)現(xiàn)該接口進(jìn)行某些操作,我們這個(gè)程序就直接打印一些信息,不做復(fù)雜的操作

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";
    }
}

除此之外,我們還要定義兩個(gè)枚舉類,分別表示狀態(tài)和動(dòng)作

public enum StateEnum {
    // 打籃球
    PLAY_BASKETBALL,
    // 唱跳rap
    SING_DANCE_RAP
}
public enum ActionEnum {
    // 音樂起
    MUSIC_ON,
    // 音樂結(jié)束
    MUSIC_OFF
}

上面準(zhǔn)備工作都做完后,我們需要一個(gè)狀態(tài)機(jī)類,來進(jìn)行狀態(tài)轉(zhuǎn)移

public class StateMachine {
 
    // 存儲(chǔ)狀態(tài)信息
    private List<StateTransaction> stateTransactionList;
    // 記錄當(dāng)前狀態(tài)
    private StateEnum currentState;
 
    public StateMachine(StateEnum state) {
        currentState = state;
        stateTransactionList = new ArrayList<>();
    }
 
    // 添加一條狀態(tài)信息
    public StateTransaction addone() {
        StateTransaction stateTransaction = new StateTransaction();
        stateTransactionList.add(stateTransaction);
        return stateTransaction;
    }
 
    // 進(jìn)行狀態(tài)轉(zhuǎn)移
    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;
    }
 
}

上述代碼有兩個(gè)方法比較關(guān)鍵,分別是addone()和execute()

先來說addone(),方法首先初始化一個(gè)StateTransaction對(duì)象,然后放到List里面,最后將這個(gè)對(duì)象返回,我們拿到這個(gè)對(duì)象就可以往里面填內(nèi)容了。

再說說execute(),這個(gè)方法接收ActionEnum作為參數(shù),然后會(huì)遍歷列表,尋找一條當(dāng)前狀態(tài)經(jīng)過相應(yīng)動(dòng)作變化得到的下一個(gè)對(duì)象的這么一個(gè)狀態(tài)信息,如果找到了就執(zhí)行event中的handle()方法,并且將當(dāng)前狀態(tài)進(jìn)行轉(zhuǎn)移,最后將StateTransaction返回,如果沒找到就返回null。

最后來看一下初始化的方法

public class StateMachineTest {
 
    public static void main(String[] args) {
        StateMachine machine = new StateMachine(StateEnum.PLAY_BASKETBALL);
        // 打籃球的時(shí)候,一旦音樂起,就會(huì)開始唱跳rap
        machine.addone().source(StateEnum.PLAY_BASKETBALL).when(ActionEnum.MUSIC_ON)
                .target(StateEnum.SING_DANCE_RAP).how(new SingDanceRapEvent());
        // 唱跳rap的時(shí)候,一旦音樂停止,就會(huì)開始打籃球
        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);
    }
 
}

可以看到,我們直接用鏈?zhǔn)降姆椒ň湍軇?chuàng)建一條狀態(tài)轉(zhuǎn)移信息,非常優(yōu)雅

程序輸出如下

Java狀態(tài)機(jī)怎么實(shí)現(xiàn)

以上就是“Java狀態(tài)機(jī)怎么實(shí)現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI