狀態機

做时间的好朋友發表於2024-03-13

在Java程式中實現一個狀態機,你可以採用幾種不同的設計模式。

1.第一版狀態機

下面是一個簡單的狀態機實現,使用了列舉型別來表示狀態,並且使用了狀態模式(State Pattern)來實現狀態之間的轉換。

public enum ProcessState {
    STARTED,
    IN_PROGRESS,
    FINISHED
}

接下來,定義狀態機的上下文環境,它將持有當前的狀態,並允許你改變狀態:

public class ProcessContext {
    private ProcessState currentState;

    public ProcessContext() {
        currentState = ProcessState.STARTED; // 初始狀態
    }

    public void setCurrentState(ProcessState state) {
        this.currentState = state;
    }

    public ProcessState getCurrentState() {
        return currentState;
    }

    public void next() {
        switch (currentState) {
            case STARTED:
                setCurrentState(ProcessState.IN_PROGRESS);
                break;
            case IN_PROGRESS:
                setCurrentState(ProcessState.FINISHED);
                break;
            case FINISHED:
                System.out.println("Process is already finished.");
                break;
        }
    }
}

在這個例子中,ProcessContext 類擁有一個 currentState 屬性來跟蹤當前的狀態,並有一個 next 方法來轉移到下一個狀態。這是一個非常簡單的狀態機,它假定狀態的轉換是線性的(從開始到進行中,再到結束)。

2.第二種狀態機

如果你的狀態轉換更加複雜,或者你需要在狀態轉換時執行更多的邏輯,你可以為每個狀態建立一個單獨的類,並實現一個共同的介面。這樣,每個狀態都可以有自己的轉換邏輯。這是狀態模式的一個例子:

public interface ProcessState {
    void next(ProcessContext context);
}
public class StartedState implements ProcessState {
    @Override
    public void next(ProcessContext context) {
        // 在這裡實現從開始到進行中狀態的邏輯
        context.setCurrentState(new InProgressState());
    }
}

public class InProgressState implements ProcessState {
    @Override
    public void next(ProcessContext context) {
        // 在這裡實現從進行中到結束狀態的邏輯
        context.setCurrentState(new FinishedState());
    }
}

public class FinishedState implements ProcessState {
    @Override
    public void next(ProcessContext context) {
        // 已經是結束狀態,可能不需要做任何事情,或者丟擲一個異常
        System.out.println("Process is already finished.");
    }
}

public class ProcessContext {
    private ProcessState currentState;

    public ProcessContext() {
        currentState = new StartedState(); // 初始狀態
    }

    public void setCurrentState(ProcessState state) {
        this.currentState = state;
    }

    public void next() {
        currentState.next(this);
    }
}

在這個狀態模式的實現中,每個狀態都是一個實現了 ProcessState 介面的類。這樣,每個狀態類都可以有自己的 next 方法,負責處理狀態轉換的邏輯。ProcessContext 類持有一個 ProcessState 型別的物件,代表當前的狀態,並透過呼叫當前狀態的 next 方法來進行狀態轉換。

在實際應用中,狀態模式可以很好地處理更復雜的狀態機邏輯,每個狀態可以有自己的行為,甚至可以根據不同的條件轉移到不同的狀態。這種設計也更容易擴充套件和維護。

相關文章