状态模式C++详解

状态模式C++详解

状态模式由来

面向对象设计其实就是希望做到代码的责任分解(也就是说,将状态设计成类,将责任分离,这个状态应该干嘛干嘛这样)。

状态模式: 当一个对象的内在状态改变的时候,允许其改变行为。

状态模式主要解决的是当控制一个对象状态转移的表达式过于复杂的时候,将状态的判断逻辑转移到表示不同状态的一系列的类当中,可以把复杂的判断逻辑简单化

状态模式c++实现

Context.h

#ifndef CONTEXT_H_
#define CONTEXT_H_

class State;   // 声明,相当于外部符号
/* 
    这里告诉我们声明是声明,定义是定义,声明只是告诉你这里有,但是不一定在这里定义
 */ 
class Context {
 public:
  Context(State* s);
  void Request();
  void ChageState(State* s);

 private:
  State* state_;
};

#endif

Context.cc

#include "Context.h"
#include "State.h"  // 如果不包含这个头文件就没有定义,这里也是声明有个class State 定义在State.o中

Context::Context(State* s) { state_ = s; }

void Context::Request() {
    state_->Handle(this);  // 修改状态并进行该状态下应有的操作
}

void Context::ChageState(State* s) {
  delete state_;  // 清楚之前的状态4
  state_ = nullptr;
  state_ = s;
}

状态抽象类
State.h

#ifndef STATE_H_
#define STATE_H_

#include <iostream>

#include "Context.h"

class State {
 public:
  virtual void Handle(Context* con) = 0;
};

#endif

具体状态类
Sleep.h

#ifndef SLEEP_H_
#define SLEEP_H_
#include "State.h"
#include "eat.h"

// 开始睡觉时候的状态
class Sleep : public State {
 public:
  void Handle(Context* con);

 private:
};

#endif

Sleep.cc

#include "Sleep.h"

void Sleep::Handle(Context* con) {
  std::cout << "现在的状态是睡觉" << std::endl;
  std::cout << "睡醒啦该去吃饭了" << std::endl;
  State* new_state = new Eat();
  con->ChageState(new_state);  // 状态动作的转移放置在状态里面
}

eat.h

#ifndef EAT_H_
#define EAT_H_
#include "Sleep.h"
#include "run.h"

// 开始睡觉时候的状态
class Eat : public State {
 public:
  void Handle(Context* con);

 private:
};

#endif

eat.cc

#include "eat.h"
void Eat::Handle(Context* con) {
  std::cout << "现在的状态是吃饭" << std::endl;
  std::cout << "吃完饭该去运动了" << std::endl;
  State* new_state = new Run();
  con->ChageState(new_state);  // 状态动作的转移放置在状态里面
}

run.h

#ifndef RUN_H_
#define RUN_H_
#include "Sleep.h"
#include "State.h"

// 开始睡觉时候的状态
class Run : public State {
 public:
  void Handle(Context* con);

 private:
};

#endif

run.cc

#include "run.h"

void Run::Handle(Context* con) {
  std::cout << "现在的状态是运动" << std::endl;
  std::cout << "运动完该去睡觉了" << std::endl;
  State* new_state = new Sleep();
  con->ChageState(new_state);  // 状态动作的转移放置在状态里面
}

main.cc

#include "Context.h"
#include "Sleep.h"
#include "State.h"
#include "eat.h"
#include "run.h"

int main() {
  // 初始状态
  State* s = new Sleep();
  Context context(s);
  context.Request();
  context.Request();
  context.Request();
  context.Request();
  context.Request();
}

运行结果如下

现在的状态是睡觉
睡醒啦该去吃饭了
现在的状态是吃饭
吃完饭该去运动了
现在的状态是运动
运动完该去睡觉了
现在的状态是睡觉
睡醒啦该去吃饭了
现在的状态是吃饭
吃完饭该去运动了
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值