概述

很多人在说状态模式的时候总拿策略模式来进行对比,可能他们的类图会有一点类似,可我却不认为他们有多么相像。你可以阅读《Java设计模式——策略模式》这篇博客,并与本文对比,以找到蛛丝马迹。
他们最根本的差异在于策略模式是在求解同一个问题的多种解法,这些不同解法之间毫无关联;状态模式则不同,状态模式要求各个状态之间有所关联,以便实现状态转移。

定义

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


目录

文章目录

  • 概述
    • 定义
  • 目录
    • @[toc]
  • 版权说明
  • 状态模式
    • 情境
    • 状态模式类图
    • 逻辑实现
  • Ref
  • GitHub 源码
  • 征集

版权说明

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
本文作者:Q-WHai
发表日期: 2016年6月6日
本文链接:https://qwhai.blog.csdn.net/article/details/51596556
来源:CSDN
更多内容:分类 >> 设计模式


状态模式

我很喜欢具有状态转移的程序,总是感觉这里充满了无限的魅力。如果你也对状态转移的逻辑感兴趣,那么你可以阅读一下我之前的几篇博客。

  • 算法之动态规划初步(Java版)
  • 算法:模式匹配之KMP算法
  • 深入理解Aho-Corasick自动机算法
  • Trie树进阶:Double-Array Trie原理及状态转移过程详解
  • 算法:关于生成抽样随机数的这些算法

情境

看《Java 设计模式》的时候,我看到一个例子,感觉很好,拿来跟大家一起分享一下。
实体是电梯,这个大家一定不陌生。我们知道电梯主要有4种状态:电梯门关闭、电梯门打开、电梯上下运载、电梯停止。而且我们知道,电梯在门打开的时候,只能是关闭电梯门,不能是其他的任何操作。在学习状态模式之前,如果我们要编写这个逻辑,一定是长篇累读地 if … else … 。而且逻辑混乱,很难维护。当然,这里你可以使用 if … else …,因为电梯的这些状态基本是稳定的,不会有什么变动。而如果你的需求里,状态会不断更新,而你之前使用 if … else … 埋下的患根这时就会让你苦不堪言。
所以,你需要重构你的代码。

状态模式类图

逻辑实现

如果想要避免使用 if … else … 或是 switch … case …,那么我们就需要对这些条件进行封装。在学习状态模式之前,我很喜欢使用一个 Map 来解决 switch … case … 问题,而且屡试不爽。从使用 Map 来解决 switch … case … 问题中可以知道,这里的条件类必须去继承一个共同的类或是共同的接口。这里就是上面类图中的 LiftState。
LiftState.java

public abstract class LiftState {protected Context context;public void setContext(Context _context) {this.context = _context;}public abstract void open();public abstract void close();public abstract void run();public abstract void stop();
}

可能你很奇怪,为什么这里 LiftState 类里面会有一个 Context 对象。它的作用是去调节状态的变化,它就是电梯,你的电梯状态肯定是针对电梯来说的,所以组合一个 Context 一点也不奇怪。

现在来看看 LiftState 的实现类吧,就拿 StoppingState 类来说吧,其他的实现跟这个类很像,就不多贴代码了。想要详细代码的朋友可以去我的 GitHub 上下载。
StoppingState.java

public class StoppingState extends LiftState {@Overridepublic void close() {// do nothing;}@Overridepublic void open() {super.context.setLiftState(Context.openningState);super.context.getLiftState().open();}@Overridepublic void run() {super.context.setLiftState(Context.runningState);super.context.getLiftState().run();}@Overridepublic void stop() {System.out.println("电梯停止了...");}
}

在停下来的时候,我们不能让电梯关闭,因为它原本就是关闭的,我这里做法是不处理,当然你可以选择抛出异常。当电梯停下来的时候,电梯是可以打开的,所以在 open() 方法里可以将电梯的状态标识为打开状态;当然,也可以标识为运载状态。而究竟会转换成哪一种状态,就要依据实际乘客的使用情况了。
下面看看我们的关键实体 Context 是怎么实现的。
Context.java

public class Context {// 定义出所有的电梯状态public final static OpenningState openningState = new OpenningState();public final static ClosingState closeingState = new ClosingState();public final static RunningState runningState = new RunningState();public final static StoppingState stoppingState = new StoppingState();// 定一个当前电梯状态private LiftState liftState;public LiftState getLiftState() {return liftState;}public void setLiftState(LiftState liftState) {this.liftState = liftState;// 把当前的环境通知到各个实现类中this.liftState.setContext(this);}public void open() {this.liftState.open();}public void close() {this.liftState.close();}public void run() {this.liftState.run();}public void stop() {this.liftState.stop();}
}

Context 组合了所有状态,这一点不奇怪,因为它是电梯嘛。在上面的代码中,你们可能很迷惑,这里 Context 都是去调用 LiftState 接口的相应方法,哪里体现了状态的转移呢?其实状态转移的逻辑是在各自的状态里面进行的,就像上面的 StoppingState 类。如果调用了 StoppingState 类,是不是说当前 Context 里的状态是 StoppingState 呢?而它却在 open() 方法里将 Context 的状态转换成了 OpenningState 。这样就完成了状态的转换了。Context 类的作用我想只是去触发状态的转换。
下面提供一张电梯的状态转移图:


Ref

  • 《Java 设计模式》

GitHub 源码

https://github.com/qwhai/design-pattern


征集

如果你也需要使用ProcessOn这款在线绘图工具,可以使用如下邀请链接进行注册:
https://www.processon.com/i/56205c2ee4b0f6ed10838a6d

Java 设计模式——状态模式相关推荐

  1. Java设计模式——状态模式【State Pattern】

    一.引言 23种设计模式大概分为三大类: 5种(创建型模式):工厂方法模式.抽象工厂模式.单例模式.原型模式.建造者模式. 7种(结构型模式):适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组 ...

  2. java设计模式---状态模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...

  3. JAVA 设计模式 : 状态模式

    原文出处: 屌丝码农 一.引出状态模式 假设我们现在有一个糖果机项目,那么我们知道正常一般糖果机提供给用户的行为有这么几种:投入硬币.转动曲柄.退出硬币几种行为:那么糖果机呢一般有这几中状态,待机状态 ...

  4. Java设计模式—状态模式

    (尊重劳动成果,转载请注明出处:https://blog.csdn.net/qq_25827845/article/details/52468077冷血之心的博客) 目录 定义如下: 个人理解: 通用 ...

  5. Java设计模式-状态模式(State)

    核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线.隐身.忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1.可以通过改变状 ...

  6. 深入理解Java设计模式——状态模式

    目录 一.什么是状态模式 二.状态模式应用场景 三.状态模式实现 1. 需要重构的代码 四.状态模式与策略模式区别 五.状态模式实现 一.什么是状态模式 状态模式允许一个对象在其内部状态改变的时候改变 ...

  7. java设计模式-状态模式

    状态模式介绍: 当一个对象在内在状态改变时,允许改变起行为,这个对象看起来像是改变了其类. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂的情况.把状态的判断逻辑转移到表示不同状态的一 ...

  8. Java设计模式(备忘录模式-解释器模式-状态模式-策略模式-职责链模式)

    Java设计模式Ⅶ 1.备忘录模式 1.1 备忘录模式概述 1.2 代码理解 2.解释器模式 2.1 解释器模式概述 3.状态模式 3.1 状态模式概述 3.2 代码理解 4.策略模式 4.1 策略模 ...

  9. Java 有限状态机 (设计模式——状态模式)

    Java 有限状态机 (设计模式--状态模式) 编写代码的时候,有时会遇见较为复杂的swith...case...和if...else...语句.这一刻有时会想到状态机,用有限状态机替换swith.. ...

最新文章

  1. 死磕 java同步系列之ReentrantReadWriteLock源码解析
  2. 密码技术--椭圆曲线算法EDCSA数字签名及Go语言应用
  3. MySQL通过存储过程使用循环结构循环创建数据,以及批量数据的导入导出
  4. 使用jenkins实现监控嵌入式设备稳定性之二----脚本部分
  5. Fat Jar Eclipse Plug-In Tutorial
  6. 用implicit和explicit打通两种类型
  7. bzoj 3924 幻想乡战略游戏
  8. 实战 | 后端日志的前世今生
  9. 各种排序算法的总结和比较(转)
  10. 揭秘阿里百亿级云客服实时分析架构是怎么炼成的?
  11. 【UML】概念、关联、画画(一)
  12. [Pa2013]Iloczyn
  13. TCP/IP模型背后的内涵(二)
  14. Latex排版图片样式
  15. mininet-wifi安装openflow13
  16. Unirech腾讯云国际站代充-云服务器系统盘使用问题
  17. 在电信物联网平台实现SOTA远程升级
  18. IEEE调研报告:父母关于人工智能对儿童的影响的看法
  19. SQL_修改字段为NOT NULL和NULL
  20. 【2023年电工杯数学建模竞赛】选题分析+A题B题完整思路+代码分享

热门文章

  1. C++ Primer 5th笔记(9)chapter9 顺序容器 构造和赋值
  2. 机器学习(一)——熟悉tensorflow2.0
  3. [Java基础] Properties类的基本操作和介绍
  4. [HOW TO]-github/gitee私有项目用户名密码免输入
  5. [reference]-Features_in_A-profile
  6. GPTEE中的Crypto API的使用
  7. kali2.0部署docker
  8. C++简单使用priority_queue
  9. python按正则方式搜索文件
  10. 160个Crackme030之一元一次方程