1. 程式人生 > 實用技巧 >c++設計模式概述之狀態

c++設計模式概述之狀態

程式碼寫的不夠規範,目的是為了縮短篇幅,實際中請不要這樣做

參看:https://www.runoob.com/design-pattern/state-pattern.html

1、概述

  這個有點抽象,我的理解是: 行為受到狀態的變化而變化。舉一個例子,籃球員動員,如果運動員這會兒狀態好,命中率(投球)就會上升。再比如人的情緒變化,可能會導致不同的行為。比如高興,是動作A,猶豫,動作B。

  

  需要用的角色,主要分為2類,A、狀態(state),B、上下文(context)。

2、抽象狀態

// 抽象狀態
class oct_state
{
public: 
    virtual void
do_action(oct_context *pct) = 0; // 用於將上下文的狀態輸出 virtual std::string to_str() = 0; protected: std::string _str_state; };

3、狀態有多種,下面舉例用到了2個A和B:

// 狀態A
class oct_state_A : public oct_state
{
    // 實現介面
    void do_action(oct_context *pct)
    {
        // 1、輸出當前髮狀態
        std::cout << "
\n狀態變化了,現在正處於狀態A\n"; // 2、告訴上下文,已經進入了狀態A if (pct) pct->set_state(this); _str_state = std::string("狀態A"); } std::string to_str() { return _str_state; } }; // 狀態B class oct_state_B : public oct_state { void do_action(oct_context *pct) {
// 1、輸出當前髮狀態 std::cout << "\n狀態變化了,現在正處於狀態B\n"; // 2、告知上下文,進入了狀態B if (pct) pct->set_state(this); _str_state = std::string("狀態B"); } std::string to_str() { return _str_state; } };

4、上下文(context)

class oct_context
{
public:
    void set_state(oct_state *ps)
    {
        if (ps)
            _pstate = ps;
    }

    oct_state * get_state() { return _pstate; }

private:
    oct_state    *_pstate = nullptr;
};

5、呼叫

void call_state()
{
    // 1、建立上下文和狀態AB
    std::unique_ptr<oct_context> pcontext(new oct_context);
    std::unique_ptr<oct_state> pstateA(new oct_state_A);
    std::unique_ptr<oct_state> pstateB(new oct_state_B);

    if (!pcontext || !pstateA || !pstateB)
    {
        std::cout << "\n建立狀態AB或者建立上下文物件失敗\n";
        return;
    }

    // 1、進入狀態A
    std::cout << "\n1、進入狀態A\n";
    pstateB->do_action(pcontext.get());

    std::cout << "\n上下文輸出:" << pcontext->get_state()->to_str().c_str() << endl;;

    // 2、進入狀態B
    std::cout << "\n\n\n\n-----------------------------------\n2、進入狀態B\n";
    pstateB->do_action(pcontext.get());
    std::cout << "\n上下文輸出:" << pcontext->get_state()->to_str().c_str() << endl;;

}

6、結果: