功能
允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类
解决
- 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为
- 何时使用:代码中包含大量与对象状态有关的条件语句
- 如何解决:将各种具体的状态类抽象出来
- 关键代码:状态模式的接口中有一个或者多个方法
优缺点
- 优点:
- 封装了转换规则
- 枚举可能的状态,在枚举状态之前需要确定状态种类
- 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为
- 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块
- 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数
- 缺点:
- 状态模式的使用必然会增加系统类和对象的个数
- 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
- 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码
应用场景
- 应用实例:打篮球的时候运动员可以有正常状态、不正常状态和超常状态
- 使用场景:
- 行为随状态改变而改变的场景
- 条件、分支语句的代替者
- 注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个
简单示例代码部分
State.hpp
#ifndef _STATE_H_
#define _STATE_H_
#include <iostream>
using namespace std;
class Context;
class State
{
public:
State(){}
virtual ~State(){}
virtual void OperationInterface(Context* con)=0;
virtual void OperationChangeState(Context*) = 0;
protected:
bool ChangeState(Context* con,State* st);
private:
//bool ChangeState(Context* con,State* st);
};
class ConcreteStateA:public State {
public:
ConcreteStateA(){}
virtual ~ConcreteStateA(){}
virtual void OperationInterface(Context* ){
cout<<"ConcreteStateA::OperationInterface......"<<endl;
}
virtual void OperationChangeState(Context* con);
};
class ConcreteStateB:public State {
public:
ConcreteStateB(){}
virtual ~ConcreteStateB(){}
virtual void OperationInterface(Context* ){
cout<<"ConcreteStateB::OperationInterface......"<<endl;
}
virtual void OperationChangeState(Context*);
};
class Context{
public:
Context(){}
Context(State* state){
this->_state=state;
}
~Context(){
delete _state;
}
void OperationInterface(){
_state->OperationInterface(this);
}
void OperationChangState(){
_state->OperationChangeState(this);
}
private:
friend class State; //表明在State类中可以访问 Context 类的 private 字段
bool ChangeState(State* state){
this->_state = state;
return true;
}
private:
State* _state;
};
void State::OperationInterface(Context* con) {
cout<<"State::.."<<endl;
}
bool State::ChangeState(Context* con,State* st) {
con->ChangeState(st);
return true;
}
void ConcreteStateA::OperationChangeState(Context* con){
OperationInterface(con);
this->ChangeState(con,new ConcreteStateB());
}
void ConcreteStateB::OperationChangeState(Context* con){
OperationInterface(con);
this->ChangeState(con,new ConcreteStateA());
}
#endif
main.cpp
#include "State.h"
#include <iostream>
using namespace std;
int main() {
State* st = new ConcreteStateA();
Context* con = new Context(st);
con->OperationInterface();
con->OperationInterface ();
con->OperationInterface();
if (con != NULL) delete con;
if (st != NULL) st = NULL;
return 0;
}
来源:CSDN
作者:听峰问雨
链接:https://blog.csdn.net/qazsatan/article/details/104296101