狀態模式 (State Pattern) 是一種用於實現狀態機的物件導向方法。主要目的是將一個物件的多種狀態封裝在不同的類別中,從而使狀態轉換更為靈活和可維護
Context (上下文): 保留狀態並代表客戶端與之互動的物件
State (狀態): 定義一個介面來封裝與 Context 物件的某一狀態相關的行為
ConcreteState (具體狀態): 實現 State 介面,代表 Context 的某一具體狀態
我們可以用以下輔助圖表來幫助我們更好的設計與簡化 States 及 Actions 之間的關係:
// 定義狀態介面
class State {
public:
    virtual ~State() {}
    virtual void review() = 0;
    virtual void publish() = 0;
};
// 實作 Draft 狀態
class Draft : public State {
public:
    void review() override {
        std::cout << "Reviewing the draft document.\n";
    }
    void publish() override {
        std::cout << "Draft document cannot be published.\n";
    }
};
// 實作 Moderation 狀態
class Moderation : public State {
public:
    void review() override {
        std::cout << "Document is under moderation. Review again.\n";
    }
    void publish() override {
        std::cout << "Moderated document is now published.\n";
    }
};
// 實作 Publish 狀態
class Publish : public State {
public:
    void review() override {
        std::cout << "Published document cannot be reviewed.\n";
    }
    void publish() override {
        std::cout << "Document is already published.\n";
    }
};
// 定義 Document 類別,其中包含狀態
class Document {
private:
    State* state; // 當前狀態
public:
    Document(State* initialState) : state(initialState) {}
    // 設定新的狀態
    void setState(State* newState) {
        delete state;
        state = newState;
    }
    // 執行 review 行為
    void review() {
        state->review();
    }
    // 執行 publish 行為
    void publish() {
        state->publish();
    }
    ~Document() {
        delete state;
    }
};
int main() {
    // 初始化狀態和 Document
    State* draft = new Draft();
    Document doc(draft);
    // 執行行為
    std::cout << "Current state: Draft\n";
    doc.review();
    doc.publish();
    // 改變狀態到 Moderation
    std::cout << "\nChanging state to: Moderation\n";
    doc.setState(new Moderation());
    // 執行行為
    doc.review();
    doc.publish();
    // 改變狀態到 Publish
    std::cout << "\nChanging state to: Publish\n";
    doc.setState(new Publish());
    // 執行行為
    doc.review();
    doc.publish();
}