状态模式

模式定义

状态模式(state),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

模式动机

  • 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
  • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式了。

UML类图

源码实现

  • state.h
#include <string>
class People; class State
{
public:
State(std::string context);
virtual ~State();
virtual void Handle(People* people) = 0; std::string Content();
protected:
std::string m_Content; private:
int m_Time;
};
  • people.h
#include "state.h"

class People
{
public:
People(State* state);
void ChangeState(State* state);
void Show();
void SetTime(int time);
int Time();
private:
int m_Now;
State* m_State;
};
  • people.cpp
#include <iostream>
#include "people.h" People::People(State* state)
:m_State(state)
{ } void People::ChangeState(State* state)
{
m_State = state;
} void People::Show()
{
std::cout << "来吧,展示!" << std::endl;
std::cout << "当前状态:" << m_State->Content() << std::endl;
} void People::SetTime(int time)
{
m_Now = time;
m_State->Handle(this);
} int People::Time()
{
return m_Now;
}
  • lifestate.h
#include "state.h"

class LifeState : public State
{
public:
LifeState(std::string content = "生活状态");
void Handle(People *people) override;
};
  • lifestate.cpp
#include "lifestate.h"
#include "workstate.h"
#include "people.h" LifeState::LifeState(std::string content)
:State(content)
{ } void LifeState::Handle(People *people)
{
int time = people->Time();
if(time > 9 && time < 18)
people->ChangeState(new WorkState());
}
  • main.cpp
#include <iostream>
#include <memory>
#include "people.h"
#include "workstate.h"
#include "playstate.h"
#include "lifestate.h" using namespace std; int main()
{
std::shared_ptr<State> state1 = std::make_shared<WorkState>();
People p(state1.get()); p.Show();
p.SetTime(9);
p.Show();
p.SetTime(11);
p.Show();
p.SetTime(13);
p.Show();
p.SetTime(20);
p.Show();
p.SetTime(22);
p.Show();
return 0;
}
  • 运行结果

来吧,展示!

当前状态:工作状态

来吧,展示!

当前状态:工作状态

来吧,展示!

当前状态:工作状态

来吧,展示!

当前状态:玩儿乐状态

来吧,展示!

当前状态:生活状态

优点

模式的优点

  • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。

    将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换。

  • 消除庞大的条件分支语句。

  • 状态模式通过把各种状态转移逻辑分布到state的子类之间,来减少相互之间的依赖。

缺点

模式的缺点

  • 每个子状态跳转到另外一个子状态是固定的,不能够灵活设置下一个状态,也就是说状态之间装换最好是一对一的,否则就又会出现一个庞大的分支语句。从这点上来看还有点像职责链模式。

状态模式(c++实现)的更多相关文章

  1. StatePattern(状态模式)

    /** * 状态模式 * @author TMAC-J * 状态模式和策略模式很像,其实仔细研究发现完全不一样 * 策略模式各策略之间没有任何关系,独立的 * 状态模式各状态之间接口方法都是一样的 * ...

  2. 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)

    说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...

  3. php实现设计模式之 状态模式

    <?php /*状态模式:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.(行为模式) * * 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做 ...

  4. Java 策略模式和状态模式

    本文是转载的,转载地址:大白话解释Strategy模式和State模式的区别 先上图: 本质上讲,策略模式和状态模式做得是同一件事:去耦合.怎么去耦合?就是把干什么(语境类)和怎么干(策略接口)分开, ...

  5. javascript - 状态模式 - 简化分支判断流程

    状态模式笔记   当一个对象的内部状态发生改变时,会导致行为的改变,这像是改变了对象   状态模式既是解决程序中臃肿的分支判断语句问题,将每个分支转化为一种状态独立出来,方便每种状态的管理又不至于每次 ...

  6. C#设计模式系列:状态模式(State)

    1.状态模式简介 1.1>.定义 状态模式的核心思想是允许一个对象在它的内部状态改变时改变它的行为,即不同的状态对应不同的行为. 状态模式的针对性很强,当有状态变化的时候可以选择状态模式. 1. ...

  7. 十一个行为模式之状态模式(State Pattern)

    定义: 当一个对象有多个状态,并且在每个状态下有不同的行为,可以使用状态模式来在其内部改变状态时改变其行为,而客户端不会察觉状态的改变,仍使用同样的方法或接口与对象进行交互. 结构图: Context ...

  8. java设计模式之状态模式

    状态模式 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 状态模式UML图 上下文环境(Context):它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关 ...

  9. iOS - 在工程中试玩状态模式

    做了一个项目,项目中一个藏品详情界面针对不同用户,和用户所处于的状态的不同,展示的效果和操作的权限都会不同.想到了状态模式,从来没有用过,赶紧学一下然后用一用.期待兴奋 看了这么多的博客,终于找到一个 ...

  10. [Head First设计模式]生活中学设计模式——状态模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

随机推荐

  1. dB是乘以10还是乘以20

    dB即分贝(decibel),经常用来表示信号的大小.然而,今天在学习计算机网络的时候发现分贝的公式有两种:10lg(X) 或者 20lg(X) 很迷惑所以查找资料.得到的结果是dB在表示功率的时候用 ...

  2. EPLAN文本输入怎么转行,路径功能文本换行方法

    EPLAN文本输入怎么转行,路径功能文本换行方法 在输入文本时,按CTRL+ENTER可以将字体换行 Ctrl+回车键

  3. MySQL的使用方法和视图、索引、以及存储过程的一些简单方法

    一,基本概念 1, 常用的两种引擎:         (1) InnoDB        a,支持ACID,简单地说就是支持事务完整性.一致性:         b,支持行锁,以及类似ORACLE的一 ...

  4. 点击提交按钮,屏幕会出现闪烁问题,element.style问题

    点击提交按钮,屏幕会出现闪烁问题 通过后台调试发现,在点击的按钮的时候会给body添加一个padding值,而且会出现怎么都修改不了的问题,会发现里面会有 element.style的值,这其实是一种 ...

  5. JAVA 字节流 与 字符流 的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢? 字节流 在操作时本身不会用到缓冲区(内存),是文件本身直接操作的 字符流 在操作时使用了缓冲区,通过缓冲区再操作文 ...

  6. 韩顺刚-tcp报文头协议详细分析第一包数据:序号是0,发送数据的长度是0,因为没有收到对端的数据,所以确认号是0, Syn的标志位设置成1,这里没有发送的数据,只发送TCP的20个字节的头部

    TCP报文段首部格式 大部分TCP报文头部都是20个字节,有的数据包要加上选项. 上面一行代表4个字节,源端口和目的端口都是2个字节. TCP协议是面向字节流的协议 TCP是一段一段分块的发送数据的 ...

  7. 一条update SQL语句是如何执行的

    一条更新语句的执行过程和查询语句类似,更新的流程涉及两个日志:redo log(重做日志)和binlog(归档日志).比如我们要将ID(主键)=2这一行的值加(c:字段)1,SQL语句如下: upda ...

  8. 入门大数据---Spark车辆监控项目

    一.项目简介 这是一个车辆监控项目.主要实现了三个功能: 1.计算每一个区域车流量最多的前3条道路. 2.计算道路转换率 3.实时统计道路拥堵情况(当前时间,卡口编号,车辆总数,速度总数,平均速度) ...

  9. docker创建tomcat容器

    配置阿里云镜像地址:先在阿里云搜索:容器镜像服务  --> 最下面找到 容器加速服务  docker配置  etc目录下 创建docker文件夹 mkdir --->docker  --- ...

  10. 【写法总结】$.ajax与$.post、$.get 写法区别

    原文: https://www.cnblogs.com/asdyzh/p/9807264.html   后台代码: [HttpPost] public string DoLogin(string us ...