1. 程式人生 > >直譯器模式與狀態模式

直譯器模式與狀態模式

直譯器模式

直譯器模式是行為型模式之一,描述瞭如何為簡單的語言定義一套語法,如何在該語言中表示一個句子,以及如何解釋這些句子,然後執行相應的動作和行為!
角色及職責
這裡寫圖片描述
Context
直譯器上下文環境類。用來儲存直譯器的上下文環境,比如需要解釋的文法等。
AbstractExpression
直譯器抽象類。
ConcreteExpression
直譯器具體實現類。
案例

#include <iostream>
using namespace std;


/*上下文環境--客戶端通過他獲取解釋結果*/
class Context
{
public:
    Context
(int num)//上下文環境需要一個建構函式--存放待解釋的資訊 { this->m_num = num; } int getNum() { return m_num; } int getRes()//返回結果 { return m_res; } void setNum(int num) { this->m_num = num; } void setRes(int res) { this->m_res = res; } private
: /*待解釋的內容*/ int m_num; /*解釋後的結果*/ int m_res; }; /*抽象直譯器--定義瞭解釋行為函式*/ class Expression { public: virtual void interpreter(Context *context) = 0; private: Context *m_context;//直譯器裡面含有上下文環境做成員變數--以便提取待解釋的資訊 }; //加法--具體直譯器--實現基類純虛擬函式 class PlusExpression : public Expression { public
: PlusExpression()//純虛擬函式 { this->context = NULL; } virtual void interpreter(Context *context)//模擬解釋的過程 { int num = context->getNum(); num ++; context->setNum(num);//設定解釋結果到上下文環境 context->setRes(num); } private: Context *context;//直譯器裡面含有上下文環境做成員變數--以便提取待解釋的資訊 }; // 減法--具體直譯器 class MinusExpression : public Expression { public: MinusExpression() { this->context = NULL; } virtual void interpreter(Context *context) { int num = context->getNum(); num -- ; context->setNum(num); context->setRes(num); } private: Context *context; }; /*測試案例*/ int main() { Expression *expression = NULL; Context *context = NULL; Expression *expression2 = NULL; context = new Context(10); cout << context->getNum() << endl; expression = new PlusExpression; expression->interpreter(context); cout << context->getRes() << endl; expression2 = new MinusExpression; expression2->interpreter(context); cout << context->getRes() << endl; return 0; }

狀態模式

State模式也叫狀態模式,是行為設計模式的一種。State模式允許通過改變物件的內部狀態而改變物件的行為,這個物件表現得就好像修改了它的類一樣。
狀態模式主要解決的是:控制一個物件的狀態進行轉換的條件表示式,過於複雜時的情況(條件表示式控制著物件狀態的轉換)。把狀態的判斷邏輯轉移到到表現不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。
這裡寫圖片描述
這裡寫圖片描述
角色及職責
這裡寫圖片描述
Context:使用者物件
擁有一個State型別的成員,以標識物件的當前狀態;
State:抽象狀態類
封裝與Context的特定狀態相關的行為介面; –同時狀態類完成任務的行為函式需要一個上下文環境/使用者物件做引數。
ConcreteState:具體狀態類
實現了一個與Context某個狀態相關的具體行為。
適用於:
物件的行為,依賴於它所處的當前狀態。行為隨狀態改變而改變的場景。
案例

/*******************************
 *解決--表示物件狀態的表示式複雜的情況
 * --大量的case語句
 * --case與具體行為又相互包裹在一起
 * --不能將邏輯和行為實現很好的分離
 * --這列問題適合用狀態模式解決
 *
 * 一個狀態類對應於一個case語句應該有的行為
 * --多個具體的狀態類有一個共同的基類--抽象狀態類
 * --多型
 *
 * 抽象狀態類有提供給使用者物件/上下文環境使用,表示當前物件的狀態
 * --一般來說抽象類都有一個公共介面,子類需要實現--執行具體行為
 *
 * 上下文環境通過自己的狀態類成員變數決定執行什麼操作以對應狀態物件的邏輯
 *
*******************************/



#include <iostream>
#include <string>
using namespace std;

class Worker;
class State1;
class State2;
class State;

/*抽象狀態類*/
class State
{
public:
    virtual void doSomething(Worker *w) = 0;
};


/*上下文環境--使用者物件--他的狀態會改變--對應不同的行為*/
class Worker
{
public:
    Worker();

    void doThing()//核心函式--使用者物件執行自己的行為--引起狀態類成員函式的執行--狀態不同--行為不同
    {
        m_curstate->doSomething(this);
    }

    int getHour()
    {
        return m_hour;
    }

    void setHour(int hour)
    {
        m_hour = hour;
    }

    State * getState()
    {
        return m_curstate;
    }

    void setState(State * state)
    {
        m_curstate = state;
    }

private:
    int m_hour;
    State * m_curstate;
};

/*具體狀態類--因為在行為函式裡面要使用到State2的例項,但此時沒有給出State2的完整實現
--所以需要先進性宣告,在State2完整實現以後再進行函式的實現*/
class State1:public  State
{
public:

    virtual void doSomething(Worker *w);

};

/*具體狀態類*/
class State2:public  State
{
public:
    virtual void doSomething(Worker *w);
};

/*具體狀態類的行為函式的實現*/
void State1::doSomething(Worker *w)
{
    if(w->getHour() == 7 || w->getHour() == 8)
    {
        cout<<"eating!"<<endl;
    }\
    else
    {
        delete w->getState();
        w->setState(new State2);//進入下一個狀態
        w->getState()->doSomething(w);
    }
}


/*具體狀態類的行為函式的實現*/
void State2::doSomething(Worker *w)
{
    if(w->getHour() == 9 || w->getHour() == 8)
    {
        cout<<"working!"<<endl;//具體行為--和邏輯分離
    }\
    else
    {
        delete w->getState();//不滿足狀態2要進入下一個狀態
        w->setState(new State1);//後面沒有更多的狀態。返回到第一個狀態,否則一直進入下一個狀態
        cout<<"error! coming to the initial state"<<endl;
    }
}


/*使用者物件的建構函式--需要用到State1--所以後置實現*/
Worker::Worker()
{
    m_curstate = new State1;
}


/*測試案例*/
int main()
{
    Worker *w1 = new Worker;
    w1->setHour(7);
    w1->doThing();

    w1->setHour(9);
    w1->doThing();

    w1->setState(new State2);
    w1->setHour(7);
    w1->doThing();

    delete w1;
    return 0;
}