您的位置:首页 > 其它

State模式

2015-07-19 13:15 330 查看
一个事物,在不同的状态下会有不同的动作,还可以变化到另一个状态,在开发时有时会遇到这样的事物。有限状态机就是这样的一个事物,在实现时用到了switch case来解决的,但是当状态不多时,这样可以解决,如果状态很多,switch case就会变得难以维护。switch case还有有个缺点就是逻辑和实现没有分离,动作的代码直接写在了逻辑中,使得维护和扩展变得困难。

State模式就是解决这个问题的。其类图结构如下:



实现:

//State.h

//State.h

#ifndef _STATE_H_
#define _STATE_H_

class Context;//forward declartion
class State
{
public:
    State();
    virtual ~State();
    virtual void OperationInterface(Context*) = 0;
    virtual void OperationChangeState(Context*) = 0;
protected:
    bool ChangeState(Context* con, State* st);
};

class ConcreteStateA :public State
{
public:
    ConcreteStateA();
    virtual ~ConcreteStateA();
    virtual void OperationInterface(Context*) ;
    virtual void OperationChangeState(Context*);
};

class ConcreteStateB :public State
{
public:
    ConcreteStateB();
    virtual ~ConcreteStateB();
    virtual void OperationInterface(Context*) ;
    virtual void OperationChangeState(Context*);
};

#endif


//State.cpp

//State.cpp

#include"State.h"
#include"Context.h"
#include<iostream>
using namespace::std;

State::State()
{}
State::~State()
{}
bool State::ChangeState(Context* con, State* st)
{
    con->ChangeState(st);
    return true;
}

ConcreteStateA::ConcreteStateA()
{}
ConcreteStateA::~ConcreteStateA()
{}

void ConcreteStateA::OperationInterface(Context* con)
{
    cout << "ConcreteStateA::OperationInterface..." << endl;
}
void ConcreteStateA::OperationChangeState(Context* con)
{
    OperationInterface(con);
    ChangeState(con, new ConcreteStateB());
}

ConcreteStateB::ConcreteStateB()
{}
ConcreteStateB::~ConcreteStateB()
{}
void ConcreteStateB::OperationInterface(Context* con)
{
    cout << "ConcreteStateB::OperationInterface..." << endl;
}
void ConcreteStateB::OperationChangeState(Context* con)
{
    OperationInterface(con);
    ChangeState(con, new ConcreteStateA());
}


//Context.h

//Context.h

#ifndef _CONTEXT_H_
#define _CONTEXT_H_

class State;
class Context
{
public:
    Context();
    Context(State* st);
    ~Context();
    void OperationInterface();
    void OperationChangeState();
private:
    friend class State;//在State实例中可以访问ChangeState
    bool ChangeState(State* st);

    State* state_;
};

#endif


//Context.cpp

//Context.cpp

#include"Context.h"
#include"State.h"
#include<iostream>

Context::Context()
{}
Context::~Context()
{
    delete state_;
}
Context::Context(State* st)
{
    state_ = st;
}
void Context::OperationInterface()
{
    state_->OperationInterface(this);
}
bool Context::ChangeState(State* state)
{
    if (state_ != NULL)
        delete state_;
    state_ = state;
    return true;
}
void Context::OperationChangeState()
{
    state_->OperationChangeState(this);
}


//main.cpp

//main.cpp

#include"State.h"
#include"Context.h"
#include<iostream>
int main()
{
    State* st = new ConcreteStateA();
    Context* con = new Context(st);
    con->OperationInterface();
    con->OperationChangeState();
    con->OperationInterface();
    if (con != NULL)
        delete con;
    return 0;
}


在上面实现中,State声明为Context的友元,方便State访问Context的protected方法。State和它的子类将Context*作为方法的参数,通过指针调用Context的方法,这正是区别Strategy模式的地方。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: