iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
自我挑戰組

30天重新認識C++系列 第 28

第二十八天 C++ 設計模式 - 七

  • 分享至 

  • xImage
  •  

今天就緊接著把最後一個設計模式 - 狀態模式 給介紹完吧!

狀態模式

狀態模式是一種行為設計模式,讓我們在一個物件的內部狀態變化時改變其行為,使其看上去就像改變了自身所屬的類別一樣

有個簡單的例子,像是我們在部落格之類的網站上發表文章,文章發送前的狀態可能是 草稿審核中以及已發佈等等的狀態,這種模擬就可以用狀態模式實現

下面就用文章的例子來看看,假設三種狀態 草稿 可以編輯確認後轉 審核中 審核過了後轉 已發佈

class Document;

class State
{
protected:
    Document* doc_;

public:
    void set_doc(Document* doc)
    {
        this->doc_ = doc;
    }

    virtual void Change() = 0;
    virtual void Check() = 0;
    virtual void Confirm() = 0;
};

class DraftState : public State {
public:
    void Change() override;
    void Check() override;
    void Confirm() override;
};
class ReviewState : public State {
public:
    void Change() override;
    void Check() override;
    void Confirm() override;
};

class Document
{
private:
    State* state_;
public:
    Document()
    {
        this->Transition(new DraftState);
    }

    void Transition(State* state)
    {
        if (this->state_ != nullptr)
        {
            delete this->state_;
        }
        this->state_ = state;
        this->state_->set_doc(this);
    }

    void Review()
    {
        this->state_->Check();
    }

    void Write()
    {
        this->state_->Change();
    }

    void Confirm()
    {
        this->state_->Confirm();
    }
};

class PublishState : public State {
public:
    void Change() override
    {
        cout << "Publish no change " << endl;
    }

    void Check() override
    {
        cout << "Publish no check " << endl;
    }

    void Confirm() override
    {
        cout << "Doc is publish " << endl;
    }
};

void DraftState::Change()
{
    cout << "Draft can change " << endl;
}

void DraftState::Check()
{
    cout << "Draft to check " << endl;
    this->doc_->Transition(new ReviewState);
}

void DraftState::Confirm()
{
    cout << "Draft no confirm " << endl;
}

void ReviewState::Change()
{
    cout << "Review no change " << endl;
}

void ReviewState::Check()
{
    cout << "Review no check " << endl;
}

void ReviewState::Confirm()
{
    cout << "Review to confirm " << endl;
    this->doc_->Transition(new PublishState);
}

int main() {
    Document* doc = new Document;
    doc->Write();
    doc->Review();
    doc->Confirm();

    return 0;
}

可以看到狀態模式能定義出各種狀態該做的事情在不同類別中,但代價是更多更複雜的程式碼,如果狀態很少或是很少改變狀態就可以不用考慮狀態模式唷!


今天就將設計模式之前欠的部分補齊囉~期待完賽 XD

參考資料

C++ 狀態模式


上一篇
第二十七天 C++ 設計模式 - 六
下一篇
第二十九天 C++ Tree
系列文
30天重新認識C++30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言