目录

一、关于状态模式

二、案例

三、附录 完整代码


一、关于状态模式

状态模式是行为设计模式的一种,状态模式中的行为是由状态决定的,不同的状态下有不同的行为。状态模式将对象的行为封装在不同的状态对象中。

状态模式中的角色:

1)环境角色:也称为上下文,它定义了客户需要的接口,负责保持和切换状态。

2)抽象状态角色:定义一个接口,用来封装环境对象中的特定状态所对应的行为。

3)具体状态角色:实现抽象状态所对应的行为。

二、案例

用“状态模式”实现进程状态转换的程序。

操作系统中进程的五种状态,包括创建状态、就绪状态、阻塞状态、执行状态和结束状态,五种状态之间的转换以及转换条件如下图。(图片来自计算机操作系统教材)。

进程状态转换程序类图如下。

类图解析:

1)首先定义一个抽象状态角色,即状态接口AbstractState,状态接口中规定了两个方法。第一个是accept(Message msg) 方法,该方法的作用是接收信息,并且根据当前的状态和接收到的消息判断接下来切换到进程的哪一状态;第二个是stateName()方法,该方法输出当前进程所处的状态。

2)然后定义具体状态角色,实现状态接口AbstractState。分别定义五个具体状态类实现状态接口,分别为创建状态类NewState、就绪状态类ReadyState、阻塞状态类BlockedState、执行状态类RunningState以及结束状态类EndState,并且五种具体状态类均重写了接口中的两个方法。

3)定义环境角色,即CurrentState类,负责保持当前状态和状态转换。该类定义了一个状态属性,两个方法setAs(AbstractState as)和getAs()。

4)设置了一个枚举类型的消息类Message定义进程状态转换图中所有的消息。包括"MSG_EnterReadyQueue"为“进入就绪队列”消息、"MSG_IOComplete"为“I/O完成”消息、"MSG_IORequest"为“I/O请求”消息、"MSG_ProcessSchedule"为“进程调度”消息、"MSG_TimeSliceEnd"为“时间片用完”消息、"MSG_ProcessEnd"为“进程执行结束”消息。

那么是如何做到状态转换效果的呢?

是这样做到转换效果的:调用当前状态的accept(Message msg)方法,传递当前的消息。在当前状态的具体类中判断是哪个消息,根据消息判断当前要做出什么动作,即当前状态转换到什么状态,然后调用CurrentState类中的setAs(AbstractState as)方法,将目标状态对象赋予CurrentState类中的属性,即可完成状态转换。

例如,现在创建状态转换到就绪状态,需要接收消息"MSG_EnterReadyQueue",即“进入就绪队列”。NewState类代码如下。

public class NewState implements AbstractState{@Overridepublic void accept(Message msg) {if(msg == Message.MSG_EnterReadyQueue) {System.out.println("接收消息:" + msg);CurrentState.setAs(new ReadyState());} else {System.out.println("当前状态下接收的消息非法!!!");}}@Overridepublic void stateName() {System.out.println("现在是创建状态......");}
}

设置当前状态为创建状态的代码如下。

AbstractState as = new NewState();
CurrentState.setAs(as);

调用NewState类中的方法,表示当前状态接收消息的代码如下。

CurrentState.getAs().accept(Message.MSG_EnterReadyQueue);

当前进程处于创建状态,此时接收消息“MSG_EnterReadyQueue” ,即“进入就绪队列”,因为CurrentState类中此时属性as = new NewState(),所以CurrentState.getAs().accept(Message.MSG_EnterReadyQueue) 调用的是具体状态类NewState中的accept(Message msg)方法,该方法判断接收到的是哪种消息,当前消息是“MSG_EnterReadyQueue”,所以执行CurrentState.setAs(new ReadyState()),转换到目标状态,即就绪状态。

以下为测试的运行结果,运行结果中包含了进程中所有状态。

测试时输入命令:

java demo3.Client "进入就绪队列" "进程调度" "进程调度" "I/O请求" "I/O完成" "进程调度" "进程执行结束"

测试结果如下。

三、附录 完整代码

package demo3;
enum Message {MSG_EnterReadyQueue,MSG_IOComplete,MSG_IORequest,MSG_ProcessSchedule,MSG_TimeSliceEnd,MSG_ProcessEnding
}public interface AbstractState {public void accept(demo3.Message msg);public void stateName();
}public class NewState implements AbstractState{@Overridepublic void accept(Message msg) {if(msg == Message.MSG_EnterReadyQueue) {System.out.println("接收消息:" + msg);CurrentState.setAs(new ReadyState());} else {System.out.println("当前状态下接收的消息非法!!!");}}@Overridepublic void stateName() {System.out.println("现在是创建状态......");}
}public class ReadyState implements AbstractState {@Overridepublic void accept(Message msg) {if(msg == Message.MSG_ProcessSchedule) {System.out.println("接收消息:" + msg);CurrentState.setAs(new RunningState());} else {System.out.println("当前状态下的接收消息非法!!!");}}@Overridepublic void stateName() {System.out.println("现在是就绪状态......");}
}public class BlockedState implements AbstractState{@Overridepublic void accept(Message msg) {if(msg == Message.MSG_IOComplete) {System.out.println("接收消息:" + msg);CurrentState.setAs(new ReadyState());} else {System.out.println("当前状态下接收的消息非法!!!");}}@Overridepublic void stateName() {System.out.println("现在是阻塞状态......");}
}public class RunningState implements AbstractState{@Overridepublic void accept(Message msg) {if(msg == Message.MSG_TimeSliceEnd) {System.out.println("接收消息:" + msg);CurrentState.setAs(new ReadyState());} else if(msg == Message.MSG_IORequest) {System.out.println("接收消息:" + msg);CurrentState.setAs(new BlockedState());} else if(msg == Message.MSG_ProcessEnding) {System.out.println("接收消息:" + msg);CurrentState.setAs(new EndState());}else {System.out.println("当前状态下接收的消息非法!!!");}}@Overridepublic void stateName() {System.out.println("现在是执行状态......");}
}public class EndState implements AbstractState{@Overridepublic void accept(Message msg) {System.out.println("进程已经结束!!!");}@Overridepublic void stateName() {System.out.println("现在是结束状态...");}
}public class CurrentState {private static AbstractState as;public static AbstractState getAs() {return as;}public static void setAs(AbstractState as) {CurrentState.as = as;}
}public class Client {public static void main(String[] args) {AbstractState as = new NewState();CurrentState.setAs(as);CurrentState.getAs().stateName();for(String str: args) {switch (str) {case "进入就绪队列":CurrentState.getAs().accept(Message.MSG_EnterReadyQueue);CurrentState.getAs().stateName();break;case "进程调度":CurrentState.getAs().accept(Message.MSG_ProcessSchedule);CurrentState.getAs().stateName();break;case "时间片用完":CurrentState.getAs().accept(Message.MSG_TimeSliceEnd);CurrentState.getAs().stateName();break;case "I/O完成":CurrentState.getAs().accept(Message.MSG_IOComplete);CurrentState.getAs().stateName();break;case "I/O请求":CurrentState.getAs().accept(Message.MSG_IORequest);CurrentState.getAs().stateName();break;case "进程执行结束":CurrentState.getAs().accept(Message.MSG_ProcessEnding);CurrentState.getAs().stateName();break;default:System.out.println("非法消息!!!");break;}}}
}

状态模式,实现进程中状态的转换相关推荐

  1. 设计模式 之 状态模式//用游戏中的例子解释设计模式

    此类型的博客的写作初衷在于,整理自己平时所学的知识,随时欢迎各路大神指正 //绿色字的内容为注释 什么时候使用状态模式/状态模式有什么用? 官方的说法是,当对象有很明确的状态划分的时候:  1.一个对 ...

  2. 状态模式(Unity中使用)

    说明: Context(状态拥有者):是一个具有"状态"属性的类,可以定制相关的接口,让外界能够得知状态的改变或者通过操作让状态改变. State(状态接口类):制定状态的接口,负 ...

  3. php 状态模式,PHP设计模式之状态模式

    状态模式从字面上其实并不是很好理解.这里的状态是什么意思呢?保存状态?那不就是备忘录模式了.其实,这里的状态是类的状态,通过改变类的某个状态,让这个类感觉像是换了一个类一样.说起来有点拗口吧,先学习概 ...

  4. python 状态模式_使用状态模式自由切换登录状态

    日常开发中,登录和未登录两种状态分别有不同的操作,比如登录后才能评论.收藏.支付购买和编辑资料等操作.我们网购时看到心仪的商品,如果处于登录状态,可以加购物车或直接购买,否则会跳转到登录页面,登录后再 ...

  5. 状态模式之观察者和状态模式

    机房收费系统合作时,我们发现在上下机那儿可以用到观察者模式.状态模式和职责链模式,他们都是行为型模式,但是他们是有区别的. 观察者模式 我的博客链接:机房收费系统之观察者模式. 观察者模式:一个目标物 ...

  6. 状态模式:从工作状态,再到订单状态一点点深入学习状态模式

    状态模式 允许一个对象在其内部状态发生改变时改变其行为能力. 我刚开始看到这个模式的时候,没啥感觉,不知道这东西要说的是个啥,后来看了个案例,渐渐清楚了,这个模式本身还是比较简单的. 小菜的工作状态 ...

  7. linux进程状态d状态,Linux下进程的状态

    如下信息来自于命令man ps Here are the different values that the s, stat and state output specifiers (header & ...

  8. C#常用设计模式(Unity)——游戏场景的转换——状态模式(State)

    此文章原文来源于<设计模式与完美游戏开发>(蔡升达著),笔者只是在学习过程中受益颇多,从而进行了总结,有兴趣的读者可以去阅读原书. 1.场景的转换 当游戏比较复杂的时候,通常会设计多个场景 ...

  9. 趣谈设计模式 | 状态模式(State):如何实现游戏中的状态切换?

    文章目录 案例:马里奥积分竞赛 有限状态机 分支逻辑法 查表法 状态模式 状态模式与策略模式 总结 完整代码与文档 案例:马里奥积分竞赛 喜欢马里奥的小伙伴们都应该知道,前不久马里奥为了庆祝35周年, ...

  10. 操作系统学习笔记-2.1. 2进程的状态与转换

    操作系统学习笔记-2019 王道考研 操作系统-2.1. 2进程的状态与转换 文章目录 2进程的状态与转换 2.1知识概览 2.2进程的状态-三种基本状态 2.3进程的状态-另外两种状态 2.4进程状 ...

最新文章

  1. 【译】保护 Consul 在特定设置中免受 RCE 风险的影响
  2. 云鹊医认证审核需要多久_ISO9001质量管理体系认证审核需要准备哪些资料
  3. 以太网的分层架构_读《企业应用架构模式》记录-分层
  4. java程序设计专业介绍_简介Java编程中的Object类
  5. linux设备驱动程序架构的研究,Linux设备驱动程序学习(12)-Linux设备模型(底层原理简介)...
  6. formidable模块的使用
  7. 【教程】InstallShield使用完全教程
  8. applet 打印的属性和配置
  9. 袋鼠云数据库数据同步之flinkx1.10版入门-搭配flink1.11
  10. 微信公众号只能设置两个网页授权域名的解决方案
  11. input 起止时间_几种常用的控件(下拉框 可选框 起止日期 在HTML页面直接读取当前时间)...
  12. 概率导论(极限理论)
  13. auto.js之界面ui
  14. ssm城市旅游景点信息交流平台的设计与实现毕业设计源码290915
  15. .sbt文件的配置详解
  16. 内网和外网的区别+tcp协议ip协议详解
  17. android WIFI 信号强度检测
  18. springboot校园新闻趣事 计算机毕业设计(源码、运行环境)
  19. Ubuntu qq2009 wine 安装
  20. 有什么适合新手学的CAD快捷键?

热门文章

  1. 伍迷随想冷饭集 之 手术前后之随想
  2. Matlab仿真——基于NMPC的四旋翼无人机轨迹跟踪
  3. IntelliJ IDEA 通过文件代码模板自定义类注释
  4. IOS百度地图自定义大头针和气泡
  5. 解读 HB 5469民用飞机机舱内部非金属材料燃烧试验方法
  6. 实体类一键生成DDL语句(含注解 注释【没听错是注释】) 实体类一键生成建表语句 实体类逆向生成数据库表 支持注解注释生成 springboot项目 注解生成 注释生成 代码简单 功能强大
  7. 百度搜索引擎的使用方法
  8. 树搜索算法 及 最优解
  9. eBay词汇表(中/英对照)
  10. 多商户商城系统功能拆解08讲-平台端商品分类