一. 举例

一般汽车发动机工作时有四种状态,吸气、压缩、做功和排气。

在运行时,不同的状态会有不同的行为,当前的状态机在适当的时候会过渡到下一状态。

其实用户在使用时根本不知道当前的状态,也无需知道当前的状态。用户只需要给发动机一个初始状态,最后得到一个停止状态就行了。

结构图如下:

代码如下:

  1. //状态
  2. class State
  3. {
  4. public:
  5. virtual void Operation(Work *work) {}
  6. };
  7. //工作
  8. class Work
  9. {
  10. private:
  11. State *m_state;  //目前状态
  12. int m_step;      //步骤
  13. public:
  14. Work(State *state): m_state(state), m_step(0)
  15. {}
  16. ~Work()
  17. {
  18. delete m_state;
  19. }
  20. int GetStep()
  21. {
  22. return m_step;
  23. }
  24. void SetStep(int step)
  25. {
  26. m_step = step;
  27. }
  28. void SetState(State *state)
  29. {
  30. delete m_state;
  31. m_state = state;
  32. }
  33. void Operation()
  34. {
  35. m_state->Operation(this);
  36. }
  37. };
  38. //排气状态
  39. class ExhaustState: public State
  40. {
  41. public:
  42. void Operation(Work *work)  //排气操作
  43. {
  44. if(work->GetStep() == 4)
  45. {
  46. cout<<"Step : "<<work->GetStep()<<"排气操作"<<endl;
  47. }
  48. }
  49. };
  50. //做功状态
  51. class ActState: public State
  52. {
  53. public:
  54. void Operation(Work *work) //做功操作
  55. {
  56. if(work->GetStep() == 3)
  57. {
  58. cout<<"Step : "<<work->GetStep()<<"做功操作"<<endl;
  59. }
  60. else
  61. {
  62. work->SetState(new ExhaustState());
  63. work->Operation();
  64. }
  65. }
  66. };
  67. //压缩状态
  68. class CompressState: public State
  69. {
  70. public:
  71. void Operation(Work *work) //压缩操作
  72. {
  73. if(work->GetStep() == 2)
  74. {
  75. cout<<"Step : "<<work->GetStep()<<"压缩操作"<<endl;
  76. }
  77. else
  78. {
  79. work->SetState(new ActState());
  80. work->Operation();
  81. }
  82. }
  83. };
  84. //吸气状态
  85. class InhaleState: public State
  86. {
  87. public:
  88. void Operation(Work *work) //吸气操作
  89. {
  90. if(work->GetStep() == 1)
  91. {
  92. cout<<"Step : "<<work->GetStep()<<"吸气操作"<<endl;
  93. }
  94. else
  95. {
  96. State *p = new CompressState();
  97. work->SetState(p);
  98. work->Operation();
  99. }
  100. }
  101. };
  102. //测试代码
  103. int main()
  104. {
  105. State* st = new InhaleState(); //初始状态
  106. Work *work = new Work(st);
  107. for(int i = 1; i < 5; ++i)
  108. {
  109. work->SetStep(i);
  110. work->Operation(); //操作
  111. }
  112. delete work;
  113. return 0;
  114. }

二. 状态模式

定义:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

结构图:


使用范围:

(1)一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。(上面的例子就是这种情况)

(2)一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。

设计模式C++描述----16.状态(State)模式的更多相关文章

  1. 设计模式之第16章-代理模式(Java实现)

    设计模式之第16章-代理模式(Java实现) “现在朋友圈真是太让人蛋疼了啊.”“怎么说?”“一堆代理,各种卖东西的,看着好烦人.”“哎,删了呗.”“都是朋友,哪里好意思删啊.”“这倒也是...哎,迫 ...

  2. Java 实现状态(State)模式

    /** * @author stone */ public class WindowState { private String stateValue; public WindowState(Stri ...

  3. 状态(State)模式--设计模式

    定义与特点 1.1 定义 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的类一样. 1.2 特点 状态模式优点: 封装了转换规则,并枚举可能的状态,它将所有与某个状 ...

  4. Head First 设计模式 —— 12. 状态 (State) 模式

    思考题 public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; fi ...

  5. 状态(State)模式

    状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的 ...

  6. 设计模式(十九)State模式

    在面向对象编程中,是用类表示对象的.也就是说,程序的设计者需要考虑用类来表示什么东西.类对应的东西可能存在于真实世界中,也可能不存在于真实世界中.对于后者,可能有人看到代码后会感到吃惊:这些东西居然也 ...

  7. 《图解设计模式》读书笔记8-3 STATE模式

    目录 State模式 示例程序 实现的功能 不使用&使用状态模式对比 示例程序的类图 代码 角色和类图 角色 类图 拓展思路 分而治之 依赖于状态的处理 谁来管理状态迁移 易于增加新状态 实例 ...

  8. 设计模式C++描述----22.访问者(Visitor)模式

    一. 访问者模式 定义:表示一个作用于某对象结构中的各元素的操作.它你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 结构如下: 二. 举例 假设有一项科学实验,是用来对比两种种子在不同环 ...

  9. 设计模式C++描述----17.备忘录(Memento)模式

    一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比较适用于功能 ...

随机推荐

  1. Python验证码

    from PIL import Image, ImageDraw, ImageFont, ImageFilter import random # 随机字母: def rndChar(): return ...

  2. 使用.NET Core中创建Windows服务(一) - 使用官方推荐方式

    原文:Creating Windows Services In .NET Core – Part 1 – The "Microsoft" Way 作者:Dotnet Core Tu ...

  3. 高效解决「SQLite」数据库并发访问安全问题,只这一篇就够了

    Concurrent database access 本文译自:https://dmytrodanylyk.com/articles/concurrent-database/ 对于 Android D ...

  4. Thinkphp5.0第二篇

    查询构造器 //插入记录 $result=Db::table('think_data')->insert(['name'=>'张三','status'=>1]); //修改数据 $r ...

  5. 【JavaScript】 控制自适应高度

    <iframe src="需要连接的iframe地址" id="iframepage" name="iframepage" frame ...

  6. 《完美解决系列》Android5.0以上 Implicit intents with startService are not safe

    在Android6.0上,使用了以下代码: Intent intent = new Intent(); intent.setAction("xxx.server"); bindSe ...

  7. 基于Influxdb对InfluxDBResultMapper的一点扩展

    理想很饱满,现实很骨感. 由于业务需要"灵活可配置"的功能需求,在使用java开发Influxdb查询功能的时候,遇到了一个问题,Measurement注解的名称有可能需要动态变化 ...

  8. 【TencentOS tiny】深度源码分析(7)——事件

    引言 大家在裸机编程中很可能经常用到flag这种变量,用来标志一下某个事件的发生,然后在循环中判断这些标志是否发生,如果是等待多个事件的话,还可能会if((xxx_flag)&&(xx ...

  9. 第10项:重写equals时请遵守通用约定

      重写equals方法看起来似乎很简单,但是有许多重写方式会导致错误,而且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每个实例都只能与它自身相等.如果满足了以 ...

  10. 实验吧之【简单的登录题(】CBC字节反转攻击)

    开始刷ctf题吧  慢慢来. 实验吧---简单的登录题 题目地址:http://ctf5.shiyanbar.com/web/jiandan/index.php 随便提交一个id,看到后台set了两个 ...