狀態模式 (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();
}