C++设计模式:状态模式
1、状态模式介绍
状态模式: 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不通状态的一系列类当中,可以把复杂的判断逻辑简化。
状态模式结构:
State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
ConcreteStra类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
Contxt类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
2、C++代码
//state.h
class Context; //前置声明
class State
{
public:
State();
virtual ~State();
virtual void OperationInterface(Context*) = 0;
virtual void OperationChangeState(Context*) = 0;
protected:
bool ChangeState(Context* con, State* st);
}
//state.cpp
void State::OperationInterface(Context* con)
{
cout << "State::..." << endl;
}
bool State::ChangeState(Context* con, State* st)
{
con -> ChangeState(st);
return true;
}
//
class ConcreteStateA:public State
{
public:
ConcreteStateA();
virtual ~ConcreteStateA();
virtual void OperationInterface(Context*con)
{
cout << "ConcreteStateA::OperationInterface..." << endl;
}
virtual void OperationChangeState(Context*con)
{
OperationInterface(con);
this->ChangeState(con, new ConcreteB());
}
}
class ConcreteStateB:public State
{
public:
ConcreteStateB();
virtual ~ConcreteStateB();
virtual void OperationInterface(Context*con)
{
cout << "ConcreteStateB::OperationInterface..." << endl;
}
virtual void OperationChangeState(Context*con)
{
OperationInterface(con);
this->ChangeState(con, new ConcreteA());
}
}
//context.h
class Context
{
public:
Context();
Context(State *state)
{
this->_state = state;
}
~Context()
{
delete _state;
}
void OperationInterface()
{
_state->OperationInterface(this);
}
void OperationChangeState()
{
_state->OperationChangeState(this);
}
private:
friend classs State;//表明在State类中可以访问Context类中的private字段
bool ChangeState(State *state)
{
this->_state = state;
return true;
}
private:
State* _state;
}
//客户端代码
int main()
{
State *st = new ConcreteStateA();
Context *con = new Context(st);
con -> OperationInterface();
con -> OperationInterface();
con -> OperationInterface();
if (con != nullptr)
delete con;
if (st != nullptr)
st = nullptr;
return 0;
}
3、State模式与Strategy模式对比
State模式和Strategy模式有很大程度上的相似:他们都有一个Context类,都是通过委托给一个具有多个派生类的多态基类实现Context的算法逻辑。两者最大的差别就是State模式重派生类持有指向Context对象的引用,并通过这个引用调用Context中的方法,但是Strategy模式中就没有这种情况。因此可以说一个State实例同样是Strategy模式的一个实例,反之却不成立。实际上State模式和Strategy模式的区别还在于它们所关注的点不尽相同:State模式主要是要适应对象对于状态改变时的不同处理策略的实现,而Strategy则主要是具体算法和实现接口的解耦(coupling),Strategy模式中并没有状态的概念(虽然很多时候可以被看作是状态的概念),并且更加不关心状态的改变了。
State模式很好地实现了对象的状态逻辑和动作实现的分离,状态逻辑分布在State的派生类中实现,而动作实现则可以放在Context类中实现(这也是为什么State派生类需要拥有一个指向Context的指针)。这使得两者的变化相互独立,改变State的状态逻辑可以很容易复用Context的动作,也可以在不影响State派生类的前提下创建Context的子类来更改或替换动作实现。
State模式问题主要是逻辑分散化,状态逻辑分布到了很大的State的子类中,很难看到整个的状态逻辑图,这也带来了代码的维护问题。
总结:。