Java狀態機設計模式

一、狀態機設計模式實例

狀態機設計模式主要用於解決複雜的業務流程問題。例如,我們編寫電子商務網站,用戶可能需要先登錄,然後才能瀏覽商品,選擇商品,生成訂單,付款等等。每個步驟都可以看作狀態,而狀態之間的轉換就是狀態機模式的核心。

下面是一個簡單的狀態機實例,模擬汽車的啟動和行駛過程。汽車有兩個狀態:停止(stop)和行駛(run),並且有兩個事件:啟動(start)和停止(stop)。我們假設汽車開始時處於停止狀態,當收到啟動事件時,進入行駛狀態;當收到停止事件時,進入停止狀態。

public interface State {
    void handle();
}

public class StopState implements State {
    public void handle() {
        System.out.println("車已經停止了");
    }
}

public class RunState implements State {
    public void handle() {
        System.out.println("車正在行駛");
    }
}

public class Car {
    private State currentState;
    
    public Car() {
        this.currentState = new StopState();
    }
    
    public void setState(State state) {
        this.currentState = state;
    }
    
    public void start() {
        this.currentState = new RunState();
    }
    
    public void stop() {
        this.currentState = new StopState();
    }
    
    public void handle() {
        this.currentState.handle();
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.handle(); //輸出:"車已經停止了"
        
        car.start();
        car.handle(); //輸出:"車正在行駛"
        
        car.stop();
        car.handle(); //輸出:"車已經停止了"
    }
}

在上面的代碼中,我們定義了State介面,表示狀態,然後實現了兩個具體狀態StopState和RunState,其中handle方法表示狀態對應的行為。Car類表示上下文,即我們要控制狀態的對象,它包含一個currentState變數,表示當前狀態。setState、start、stop和handle方法分別表示設置狀態、啟動、停止和處理狀態。

通過上面的代碼,我們可以非常方便地控制汽車的啟動和停止,同時也可以擴展狀態和事件的數量,實現更加複雜的業務流程。

二、C++狀態機設計模式

C++也支持狀態機設計模式。下面是一個簡單的狀態機實例,演示了如何在C++中實現狀態機。和Java類似,我們先定義一個State基類,然後派生出兩個具體狀態類StopState和RunState,然後定義一個Context類表示上下文。

class State {
public:
    virtual void handle() = 0;
};

class StopState : public State {
public:
    virtual void handle() {
        cout << "車已經停止了" << endl;
    }
};

class RunState : public State {
public:
    virtual void handle() {
        cout << "車正在行駛" <handle();
    }
};

和Java版本的不同點在於,C++中沒有介面的概念,而是使用純虛函數。此外,C++需要手動管理內存,因此在Context類中需要定義一個析構函數。

三、LabVIEW狀態機設計模式

LabVIEW是一種數據流編程語言,也支持狀態機設計模式。在LabVIEW中,狀態機通常用Case Structure表示,每個Case表示一個狀態,Case之間的連線表示狀態之間的轉換。下面是一個簡單的狀態機實例,模擬一個燈的狀態。

首先,我們創建一個VI(虛擬儀器),然後在前面板中放置一個LED Indicator控制項表示燈的狀態。然後,我們在Block Diagram中使用Case Structure表示狀態機,其中第一個Case表示燈關閉的狀態,第二個Case表示燈打開的狀態,我們還可以添加其他的Case表示更多的狀態。

下面是LabVIEW中的代碼:


需要注意的是,在LabVIEW中,Case Structure之間的連線表示狀態之間的轉換。例如,從燈關閉的狀態轉換到燈打開的狀態,就需要點擊左側的方框,將輸出線連接到下一個Case的輸入線。這種方式讓狀態機更加直觀易懂。

四、單片機狀態機設計模式

單片機也支持狀態機設計模式。在單片機中,通常使用switch語句或者if語句表示狀態機。下面是一個簡單的狀態機實例,模擬一個LED燈的狀態。

int currentState = 0;

void stopState() {
    digitalWrite(13, LOW); //關閉LED燈
    currentState = 0;
}

void runState() {
    digitalWrite(13, HIGH); //打開LED燈
    currentState = 1;
}

void setup() {
    pinMode(13, OUTPUT); //設置13號引腳為輸出模式
}

void loop() {
    switch(currentState) {
        case 0:
            if (digitalRead(2) == HIGH) {
                runState(); //轉換到「燈打開」狀態
            }
            break;
        case 1:
            if (digitalRead(3) == HIGH) {
                stopState(); //轉換到「燈關閉」狀態
            }
            break;
    }
}

在上面的代碼中,我們定義了兩個狀態stopState和runState,然後使用一個變數表示當前狀態。在setup函數中,我們設置13號引腳為輸出模式,在loop函數中,通過switch語句控制狀態機。當currentState為0時,表示燈關閉的狀態,此時如果2號引腳的輸入為HIGH,就轉換到燈打開的狀態;當currentState為1時,表示燈打開的狀態,此時如果3號引腳的輸入為HIGH,就轉換到燈關閉的狀態。

五、C語言狀態機設計模式

C語言也支持狀態機設計模式。下面是一個簡單的狀態機實例,模擬LED燈閃爍的狀態。

#define STOP_STATE 0
#define RUN_STATE 1

int currentState = STOP_STATE;
unsigned long startTime = 0;

void stopState() {
    digitalWrite(13, LOW); //關閉LED燈
    currentState = STOP_STATE;
}

void runState() {
    digitalWrite(13, HIGH); //打開LED燈
    currentState = RUN_STATE;
    startTime = millis(); //記錄開始時間
}

void blinkState() {
    if (millis() - startTime >= 500) {
        digitalWrite(13, !digitalRead(13)); //燈閃爍
        startTime = millis(); //更新開始時間
    }
}

void setup() {
    pinMode(13, OUTPUT); //設置13號引腳為輸出模式
}

void loop() {
    switch(currentState) {
        case STOP_STATE:
            if (digitalRead(2) == HIGH) {
                runState(); //轉換到「燈打開」狀態
            }
            break;
        case RUN_STATE:
            if (digitalRead(3) == HIGH) {
                stopState(); //轉換到「燈關閉」狀態
            } else {
              blinkState(); //轉換到「燈閃爍」狀態
            }
            break;
    }
}

在上面的代碼中,我們定義了三個狀態:stopState、runState和blinkState。在setup函數中,我們設置13號引腳為輸出模式。在loop函數中,通過switch語句控制狀態機。當currentState為STOP_STATE時,表示燈關閉的狀態,此時如果2號引腳的輸入為HIGH,就轉換到燈打開的狀態;當currentState為RUN_STATE時,表示燈打開的狀態,此時如果3號引腳的輸入為HIGH,就轉換到燈關閉的狀態,否則就轉換到燈閃爍的狀態。在blinkState函數中,我們通過比較當前時間和開始時間,來模擬LED燈的閃爍效果。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/199264.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-04 19:15
下一篇 2024-12-04 19:15

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論