欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java狀態(tài)機的一種優(yōu)雅寫法分享

 更新時間:2023年04月12日 10:40:29   作者:haohulala  
狀態(tài)機是一種數學模型,對于我們業(yè)務實現有很大的幫助。我們可以用非常多的方法實現狀態(tài)機,這篇文章就來介紹一個狀態(tài)機優(yōu)雅的實現方法,希望對大家有所幫助

狀態(tài)機是一種數學模型,對于我們業(yè)務實現有很大的幫助。

我們可以用非常多的方法實現狀態(tài)機,比如用茫茫多的if-else來進行條件判斷,但是這種原始的方法并不夠優(yōu)雅,這篇文章就來介紹一個狀態(tài)機優(yōu)雅的實現方法。

話不多說,直接進入正題。

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

這個狀態(tài)轉換非常簡單,我們來試著用java實現一下

程序結構如下圖

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

public class StateTransaction {
 
    // 當前狀態(tài)
    private StateEnum currentState;
    // 相對應動作
    private ActionEnum action;
    // 下一個狀態(tài)
    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;
    }
 
}

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

  • currentState:表示當前狀態(tài)
  • action:表示相應動作
  • nextState:表示下一個狀態(tài)
  • event:表示相應事件

這個四元組的含義就是,當處于currentState狀態(tài)的時候,如果發(fā)生了action動作,就會轉移到nextState狀態(tài),并且會觸發(fā)event事件的響應。

注意看鏈式初始化的四個方法,這四個方法的定義讓狀態(tài)的初始化變得很優(yōu)雅。

接著來看一下事件,Event是一個接口,其他具體的事件實現該接口進行某些操作,我們這個程序就直接打印一些信息,不做復雜的操作

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

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

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

上面準備工作都做完后,我們需要一個狀態(tài)機類,來進行狀態(tài)轉移

public class StateMachine {
 
    // 存儲狀態(tài)信息
    private List<StateTransaction> stateTransactionList;
    // 記錄當前狀態(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;
    }
 
    // 進行狀態(tài)轉移
    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;
    }
 
}

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

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

再說說execute(),這個方法接收ActionEnum作為參數,然后會遍歷列表,尋找一條當前狀態(tài)經過相應動作變化得到的下一個對象的這么一個狀態(tài)信息,如果找到了就執(zhí)行event中的handle()方法,并且將當前狀態(tài)進行轉移,最后將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);
    }
 
}

可以看到,我們直接用鏈式的方法就能創(chuàng)建一條狀態(tài)轉移信息,非常優(yōu)雅

程序輸出如下

以上就是Java狀態(tài)機的一種優(yōu)雅寫法分享的詳細內容,更多關于Java狀態(tài)機的資料請關注腳本之家其它相關文章!

相關文章

  • Java?Dubbo服務調用擴展點Filter使用教程

    Java?Dubbo服務調用擴展點Filter使用教程

    Dubbo是阿里巴巴公司開源的一個高性能優(yōu)秀的服務框架,使得應用可通過高性能的RPC實現服務的輸出和輸入功能,可以和Spring框架無縫集成
    2022-12-12
  • Mybatis-config.xml中映射Mapper.xml文件遇到的錯誤及解決

    Mybatis-config.xml中映射Mapper.xml文件遇到的錯誤及解決

    這篇文章主要介紹了Mybatis-config.xml中映射Mapper.xml文件遇到的錯誤及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Spring Boot整合Elasticsearch實現全文搜索引擎案例解析

    Spring Boot整合Elasticsearch實現全文搜索引擎案例解析

    ElasticSearch作為基于Lucene的搜索服務器,既可以作為一個獨立的服務部署,也可以簽入Web應用中。SpringBoot作為Spring家族的全新框架,使得使用SpringBoot開發(fā)Spring應用變得非常簡單,在本案例中我們給大家介紹Spring Boot整合Elasticsearch實現全文搜索引擎
    2017-11-11
  • 在SpringBoot中配置日志級別和輸出格式的教程詳解

    在SpringBoot中配置日志級別和輸出格式的教程詳解

    在開發(fā)一個應用程序時,日志記錄是非常重要的一環(huán),SpringBoot提供了多種日志輸出方式和配置選項,本文將介紹如何在SpringBoot應用程序中配置日志級別和輸出格式,需要的朋友可以參考下
    2023-06-06
  • SpringBoot?ScheduledTaskRegistrar解決動態(tài)定時任務思路詳解

    SpringBoot?ScheduledTaskRegistrar解決動態(tài)定時任務思路詳解

    本文將從問題出發(fā),詳細介紹ScheduledTaskRegistrar類是如何解決動態(tài)調整定時任務的思路,并給出關鍵的代碼示例,幫助大家快速地上手學習
    2023-02-02
  • Spring集成Web環(huán)境與SpringMVC組件的擴展使用詳解

    Spring集成Web環(huán)境與SpringMVC組件的擴展使用詳解

    這篇文章主要介紹了Spring集成Web環(huán)境與SpringMVC組件,它是一個MVC架構,用來簡化基于MVC架構的Web應用開發(fā)。SpringMVC最重要的就是五大組件
    2022-08-08
  • J2EE項目代碼編寫規(guī)范分享

    J2EE項目代碼編寫規(guī)范分享

    這篇文章主要介紹了J2EE項目代碼編寫規(guī)范分享,需要的朋友可以參考下
    2014-10-10
  • java圖片驗證碼生成教程詳解

    java圖片驗證碼生成教程詳解

    這篇文章主要為大家詳細介紹了java圖片驗證碼生成教程,從簡單到復雜,從本地到前后臺,感興趣的小伙伴們可以參考一下
    2016-07-07
  • java多線程Future和Callable類示例分享

    java多線程Future和Callable類示例分享

    JAVA多線程實現方式主要有三種:繼承Thread類、實現Runnable接口、使用ExecutorService、Callable、Future實現有返回結果的多線程。其中前兩種方式線程執(zhí)行完后都沒有返回值,只有最后一種是帶返回值的。今天我們就來研究下Future和Callable的實現方法
    2016-01-01
  • RabbitMQ實現Work Queue工作隊列的示例詳解

    RabbitMQ實現Work Queue工作隊列的示例詳解

    工作隊列(又稱任務隊列)的主要思想是避免立即執(zhí)行資源密集型任務,而不得不等待它完成。本篇文章將記錄和分享RabbitMQ工作隊列相關的知識點,希望對大家有所幫助
    2023-01-01

最新評論