State状态模式
(一)概念
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。
状态模式的主要解决的是,当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当然,如果这个状态判断逻辑很简单,就没有必要使用状态模式了,Switch/Case可能就可以搞定了。
(二)动机
在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能会完全不同。
如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?
我们将状态逻辑和动态实现进行分离操作
(三)代码
state.h
#ifndef STATE_H_
#define STATE_H_
#include<iostream>
class Context;
//抽象状态类
class State{
public:
virtual void handle(Context* pContext) = 0;
~State() = default;
protected:
State(){}
};
//Contexte类要维护一个具体state类的实例,这个实例保存当前的状态
class Context{
private:
State* state;
public:
Context(State* state):state(state){};
//请求当前状态
void Request();
//改变状态
void ChangeState(State* state);
};
class StateA : public State{
public:
StateA(){};
~StateA() = default;
virtual void handle(Context* pContext);
};
class StateB : public State{
public:
StateB(){};
~StateB() = default;
virtual void handle(Context* pContext);
};
class StateC : public State{
public:
StateC(){};
~StateC() = default;
virtual void handle(Context* pContext);
};
#endif
state.cpp:
#include "state.h"
void Context::Request()
{
state->handle(this);
}
void Context::ChangeState(State* state)
{
this->state = state;
}
void StateA::handle(Context* pContext)
{
std::cout << "StateA";
std::cout << " 改变状态为B " << std::endl;
pContext->ChangeState(new StateB());
}
void StateB::handle(Context* pContext)
//执行该状态的行为并改变状态
{
std::cout << "StateB";
std::cout << " 改变状态为C " << std::endl;
pContext->ChangeState(new StateC());
}
void StateC::handle(Context* pContext)
{
std::cout << "StateC";
std::cout << " 改变状态为A " << std::endl;
pContext->ChangeState(new StateA());
}
main.cpp
#include<iostream>
#include"src/state.h"
using namespace std;
int main()
{
State* pState = new StateA();
Context* pContext = new Context(pState);
pContext->Request();
pContext->Request();
pContext->Request();
pContext->Request();
pContext->Request();
return 0;
}