一、狀態機設計模式實例
狀態機設計模式主要用於解決複雜的業務流程問題。例如,我們編寫電子商務網站,用戶可能需要先登錄,然後才能瀏覽商品,選擇商品,生成訂單,付款等等。每個步驟都可以看作狀態,而狀態之間的轉換就是狀態機模式的核心。
下面是一個簡單的狀態機實例,模擬汽車的啟動和行駛過程。汽車有兩個狀態:停止(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