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