一个事物,在不同的状态下会有不同的动作,还可以变化到另一个状态,在开发时有时会遇到这样的事物.有限状态机就是这样的一个事物,在实现时用到了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
//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模式的地方.