设计模式C++描述----16.状态(State)模式
一. 举例
一般汽车发动机工作时有四种状态,吸气、压缩、做功和排气。
在运行时,不同的状态会有不同的行为,当前的状态机在适当的时候会过渡到下一状态。
其实用户在使用时根本不知道当前的状态,也无需知道当前的状态。用户只需要给发动机一个初始状态,最后得到一个停止状态就行了。
结构图如下:

代码如下:
- //状态
- class State
- {
- public:
- virtual void Operation(Work *work) {}
- };
- //工作
- class Work
- {
- private:
- State *m_state; //目前状态
- int m_step; //步骤
- public:
- Work(State *state): m_state(state), m_step(0)
- {}
- ~Work()
- {
- delete m_state;
- }
- int GetStep()
- {
- return m_step;
- }
- void SetStep(int step)
- {
- m_step = step;
- }
- void SetState(State *state)
- {
- delete m_state;
- m_state = state;
- }
- void Operation()
- {
- m_state->Operation(this);
- }
- };
- //排气状态
- class ExhaustState: public State
- {
- public:
- void Operation(Work *work) //排气操作
- {
- if(work->GetStep() == 4)
- {
- cout<<"Step : "<<work->GetStep()<<"排气操作"<<endl;
- }
- }
- };
- //做功状态
- class ActState: public State
- {
- public:
- void Operation(Work *work) //做功操作
- {
- if(work->GetStep() == 3)
- {
- cout<<"Step : "<<work->GetStep()<<"做功操作"<<endl;
- }
- else
- {
- work->SetState(new ExhaustState());
- work->Operation();
- }
- }
- };
- //压缩状态
- class CompressState: public State
- {
- public:
- void Operation(Work *work) //压缩操作
- {
- if(work->GetStep() == 2)
- {
- cout<<"Step : "<<work->GetStep()<<"压缩操作"<<endl;
- }
- else
- {
- work->SetState(new ActState());
- work->Operation();
- }
- }
- };
- //吸气状态
- class InhaleState: public State
- {
- public:
- void Operation(Work *work) //吸气操作
- {
- if(work->GetStep() == 1)
- {
- cout<<"Step : "<<work->GetStep()<<"吸气操作"<<endl;
- }
- else
- {
- State *p = new CompressState();
- work->SetState(p);
- work->Operation();
- }
- }
- };
- //测试代码
- int main()
- {
- State* st = new InhaleState(); //初始状态
- Work *work = new Work(st);
- for(int i = 1; i < 5; ++i)
- {
- work->SetStep(i);
- work->Operation(); //操作
- }
- delete work;
- return 0;
- }
二. 状态模式
定义:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
结构图:

使用范围:
(1)一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。(上面的例子就是这种情况)
(2)一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
设计模式C++描述----16.状态(State)模式的更多相关文章
- 设计模式之第16章-代理模式(Java实现)
设计模式之第16章-代理模式(Java实现) “现在朋友圈真是太让人蛋疼了啊.”“怎么说?”“一堆代理,各种卖东西的,看着好烦人.”“哎,删了呗.”“都是朋友,哪里好意思删啊.”“这倒也是...哎,迫 ...
- Java 实现状态(State)模式
/** * @author stone */ public class WindowState { private String stateValue; public WindowState(Stri ...
- 状态(State)模式--设计模式
定义与特点 1.1 定义 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的类一样. 1.2 特点 状态模式优点: 封装了转换规则,并枚举可能的状态,它将所有与某个状 ...
- Head First 设计模式 —— 12. 状态 (State) 模式
思考题 public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; fi ...
- 状态(State)模式
状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式.状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的 ...
- 设计模式(十九)State模式
在面向对象编程中,是用类表示对象的.也就是说,程序的设计者需要考虑用类来表示什么东西.类对应的东西可能存在于真实世界中,也可能不存在于真实世界中.对于后者,可能有人看到代码后会感到吃惊:这些东西居然也 ...
- 《图解设计模式》读书笔记8-3 STATE模式
目录 State模式 示例程序 实现的功能 不使用&使用状态模式对比 示例程序的类图 代码 角色和类图 角色 类图 拓展思路 分而治之 依赖于状态的处理 谁来管理状态迁移 易于增加新状态 实例 ...
- 设计模式C++描述----22.访问者(Visitor)模式
一. 访问者模式 定义:表示一个作用于某对象结构中的各元素的操作.它你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 结构如下: 二. 举例 假设有一项科学实验,是用来对比两种种子在不同环 ...
- 设计模式C++描述----17.备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比较适用于功能 ...
随机推荐
- HashMap和Hashtable的联系和区别
实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用,早期的版本一般都是安全的. HashMap和Hashtable都实现了Map接口,但决定用哪一个之前先要弄清楚它们之间的分 ...
- Spring boot 梳理 - 模版引擎 -freemarker
开发环境中关闭缓存 spring: thymeleaf: cache: false freemarker: cache: false Spring boot 集成 freemarker <dep ...
- 多tomcat服务和nginx负载均衡配置
1.nginx服务安装及配置,详见:linux 配置之安装nginx 2.多个tomcat服务安装及配置,详见:linux 配置多个tomcat 3.关键配置nginx.conf文件 http { i ...
- Python celery和Redis入门安装使用(排难帖)
1.redis安装 下载地址 https://github.com/MicrosoftArchive/redis/releases,选择Redis-x64-3.2.100.msi5.8 MB下载就好了 ...
- MySQL InnoDB如何保证事务特性
如果有人问你"数据库事务有哪些特性"?你可能会很快回答出原子性.一致性.隔离性.持久性即ACID特性.那么你知道InnoDB如何保证这些事务特性的吗?如果知道的话这篇文章就可以直接 ...
- Java文件操作——File
创建File isFile().length().exists().createNewFile(). File.separator / isDirtory(). mkdir().mkdirs(). d ...
- 快学Scala 第四课 (多维数组,与Java集合的互操作)
Scala二维数组的定义: val arr2 = Array.ofDim[String](2, 2) arr2(0)(0) = "aa" arr2(1)(0) = "bb ...
- ELK 学习笔记之 elasticsearch head插件安装
elasticsearch head插件安装: 准备工作: 安装nodejs和npm https://nodejs.org/en/download/ node-v6.11.2-linux-x64.ta ...
- 【原创】go语言学习(二)数据类型、变量量、常量量
目录 1.标识符.关键字2. 变量量和常量量3. 数据类型4. Go程序基本结构 标识符.关键字 1.标识符是⽤用来表示Go中的变量量名或者函数名,以字⺟母或_开头.后⾯面跟着字⺟母 ._或数字2. ...
- ELK日志分析系统(3)-logstash数据处理
1. 概述 logspout收集数据以后,就会把数据发送给logstash进行处理,本文主要讲解logstash的input, filter, output处理 2. input 数据的输入处理 支持 ...