首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 設計模式精解:State 狀態模式實作與遞迴陷阱避坑指南

     編輯:Java 相關知識

前言:為什麼需要狀態模式?

系統中充滿「狀態」:執行緒生命週期、Hibernate 實體狀態、訂單流轉等。傳統用 if/else 或 switch 判斷會導致程式碼膨脹、難以維護,且新增狀態需修改多處邏輯。State 模式將每個狀態封裝為獨立類別,透過介面統一行為,符合開放封閉原則。

核心結構設計

  • State 介面:定義 handle() 方法,內部靜態 List<State> commands 維持狀態順序。
  • 四個具體狀態類別:Create、Start、End、Destroy,各自實作 execute() 列印狀態名並觸發下一狀態。

程式碼實作

// State 介面
public interface State {
    List<State> commands = new ArrayList<>();
    void handle();
}

// Create 狀態
public class Create implements State {
    public Create() { commands.add(this); }
    public void handle() { execute(this); }
    public void execute(State cmd) {
        System.out.println("create");
        commands.get(commands.indexOf(this) + 1).handle();
    }
}
// Start、End 類似,略...

// Destroy 狀態(含遞迴循環陷阱)
public class Destroy implements State {
    public Destroy() { commands.add(this); }
    public void handle() { execute(this); }
    public void execute(State cmd) {
        System.out.println("destroy");
        // 危險:循環呼叫導致 StackOverflowError
        commands.get(commands.indexOf(this) >= commands.size() - 1 ? 0 : commands.indexOf(this) + 1).handle();
    }
}

測試與輸出分析

public class Main {
    public static void main(String[] args) {
        State s1 = new Create();
        State s2 = new Start();
        State s3 = new End();
        State s4 = new Destroy();
        s1.handle(); // 觸發鏈式反應
    }
}

輸出結果:

create
start
end
destroy
create
start
end
destroy
... (無限循環)
Exception in thread "main" java.lang.StackOverflowError

關鍵教訓與改進方向

  1. 遞迴終止條件缺失:Destroy 強制循環導致堆疊溢位。實務上應在最後狀態 handle() 中不再呼叫下一狀態,或引入 Context 物件管理狀態轉換邏輯。
  2. 靜態 List 共享風險:介面中的 static List 導致所有實例共享同一序列,多執行緒或多流程下極易錯亂。建議改由 Context 持有狀態清單。
  3. 狀態類別爆炸:若狀態超過幾十個,類別數量激增,維護成本上升,需評估是否改用狀態機框架或表驅動方式。

最佳實踐建議

  • 引入 Context 類別封裝狀態切換邏輯,解耦狀態類別間的依賴。
  • 使用 enum 實作簡單狀態機(Java enum 可實作介面、擁有行為)。
  • 複雜流程採用成熟狀態機庫(如 Squirrel Foundation)或工作流引擎。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved