State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。
角色和职责
状态模式
上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的Concrete State对象来处理。
抽象状态(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。
具体状态(Concrete State):实现抽象状态定义的接口。
案例
State.hpp
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);
};
class ConcreteStateA : public State
{
public:
ConcreteStateA();
~ ConcreteStateA();
virtual void operationInterface(Context *con) override;
virtual void operationChangeState(Context *con) override;
};
class ConcreteStateB : public State
{
public:
ConcreteStateB();
~ ConcreteStateB();
virtual void operationInterface(Context *con) override;
virtual void operationChangeState(Context *con) override;
};
State.cpp
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.hpp
class State;
class Context
{
public:
friend class State;
Context();
Context(State *state);
~Context();
void operationInterface();
void operationChangeState();
private:
State *_state;
bool changeState(State *state);
};
Context.cpp
#include "Context.hpp"
#include "State.hpp"
Context::Context()
{
}
Context::Context(State *state)
{
_state = state;
}
Context::~Context()
{
delete _state;
}
void Context::operationInterface()
{
_state->operationInterface(this);
}
void Context::operationChangeState()
{
_state -> operationChangeState(this);
}
bool Context::changeState(State *state)
{
if(_state){
delete _state;
}
_state = state;
return true;
}
main.h
#include "State.hpp"
#include "Context.hpp"
int main()
{
State* st = new ConcreteStateA();
Context* con = new Context(st);
con->operationChangeState();
con->operationChangeState();
con->operationChangeState();
delete con;
return 0;
}
适用性:
状态模式主要解决的是当控制一个对象状态变换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
优缺点:
优点:
- 状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
- 所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换。
- 状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。
缺点:
- 状态模式的使用必然会增加系统类和对象的个数。
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。