当前位置: 首页 > news >正文

十九、状态模式

一、什么是状态模式

  状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

  状态模式包含以下主要角色:

  • 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

二、状态模式的实现

1. 抽象状态(State)

/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 15:01* @description 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。*/
public abstract class State {public abstract void behavior(Context context);
}

2. 环境(Context)


/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 15:01* @description 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。*/
public class Context {private State state;public Context(){this.state = new ConcreteStateA();}public State getState() {return state;}public void setState(State state) {this.state = state;}public void handle(){state.behavior(this);}
}

3. 具体状态(Concrete State)

  • 具体状态A
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 15:01* @description 具体状态(Concrete    State)角色:实现抽象状态所对应的行为。*/
public class ConcreteStateA extends State {@Overridepublic void behavior(Context context) {System.out.println("ConcreteStateA..................");context.setState(new ConcreteStateB());}
}
  • 具体状态B
/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 15:01* @description 具体状态(Concrete    State)角色:实现抽象状态所对应的行为。*/
public class ConcreteStateB extends State {@Overridepublic void behavior(Context context) {System.out.println("ConcreteStateB............");context.setState(new ConcreteStateA());}
}

4. 测试类


/*** @author FluffyCatkin* @version 1.0* @date 2020/1/7 0007 15:00* @description 狀態模式** 在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响对象行为的一个或多个动态变化的属性称为状态。当有状态的对象与外部事件产生互动时,其内部状态会发生改变,从而使得其行为也随之发生改变。如人的情绪有高兴的时候和伤心的时候,不同的情绪有不同的行为,当然外界也会影响其情绪变化。** 对这种有状态的对象编程,传统的解决方案是:将这些所有可能发生的情况全都考虑到,然后使用 if-else 语句来做状态判断,再进行不同情况的处理。但当对象的状态很多时,程序会变得很复杂。而且增加新的状态要添加新的 if-else 语句,这违背了“开闭原则”,不利于程序的扩展。** 以上问题如果采用“状态模式”就能很好地得到解决。状态模式的解决思想是:当控制一个对象状态转换的条件表达式过于复杂时,把相关“判断逻辑”提取出来,放到一系列的状态类当中,这样可以把原来复杂的逻辑判断简单化。* 状态模式的定义与特点:* 状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。** 状态模式是一种对象行为型模式,其主要优点如下:* 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。* 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。* 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。** 状态模式的主要缺点如下:* 状态模式的使用必然会增加系统的类与对象的个数。* 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。* 状态模式的结构与实现:* 状态模式把受环境改变的对象行为包装在不同的状态对象里,其意图是让一个对象在其内部状态改变的时候,其行为也随之改变。现在我们来分析其基本结构和实现方法。* 模式的结构:* 状态模式包含以下主要角色。环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。* 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。* 具体状态(Concrete    State)角色:实现抽象状态所对应的行为。* 状态模式的应用场景:* 通常在以下情况下可以考虑使用状态模式。当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。* 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。*/
public class Main {@Testpublic void stateMode(){Context context = new Context();context.handle();context.handle();context.handle();context.handle();}}

运行结果:

ConcreteStateA..................
ConcreteStateB............
ConcreteStateA..................
ConcreteStateB............Process finished with exit code 0c

三、应用场景

  通常在以下情况下可以考虑使用状态模式:

  • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。
  • 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。

四、优缺点分析

  状态模式是一种对象行为型模式,其主要优点如下:

  • 结构清晰,状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  • 将状态转换显示化,减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
  • 状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

  状态模式的主要缺点如下:

  • 状态模式的使用必然会增加系统的类与对象的个数。
  • 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
  • 状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。

代码地址:https://gitee.com/fluffycatkin/JavaDesignModel.git

image.png

原文出处:http://c.biancheng.net/view/1388.html

相关文章:

十九、状态模式

一、什么是状态模式 状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。 状态模式包含以下主要角色: 环境类&#xff08…...

MySQL用navicat工具对表进行筛选查找

这个操作其实很简单,但是对于没操作的人来说,就是不会呀。所以小编出这一个详细图解,希望能够帮助到大家。话不多说看图。 第一步: 点进一张表,点击筛选。 第二步: 点击添加 第三步: 选择要…...

音视频 ffplay简单过滤器

视频旋转 ffplay -i test.mp4 -vf transpose1视频反转 ffplay test.mp4 -vf hflip ffplay test.mp4 -vf vflip视频旋转和反转 ffplay test.mp4 -vf hflip,transpose1音频变速播放 ffplay -i test.mp4 -af atempo2视频变速播放 ffplay -i test.mp4 -vf setptsPTS/2音视频同…...

索引 事务 存储引擎

################索引##################### 一、索引的概念 ●索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于C语言的链表通过指针指向数据记录的内存地址)。 ●使用索引后可以不用扫描全表来…...

MySQL— 基础语法大全及操作演示!!!(事务)

MySQL—— 基础语法大全及操作演示(事务) 六、事务6.1 事务简介6.2 事务操作6.2.1 未控制事务6.2.2 控制事务一6.2.3 控制事务二 6.3 事务四大特性6.4 并发事务问题6.5 事务隔离级别 MySQL— 基础语法大全及操作演示!!&#xff01…...

xsschallenge1~13通关详细教程

文章目录 XSS 挑战靶场通关level1level2level3level4level5level6level7level8level9level10level11level12level13 XSS 挑战靶场通关 level1 通过观察发现这个用户信息可以修改 那么我们直接输入攻击代码 <script>alert(/wuhu/)</script>弹框如下&#xff1a; …...

考生作弊行为分析算法

考生作弊行为分析系统利用pythonyolo系列网络模型算法框架&#xff0c;考生作弊行为分析算法利用图像处理和智能算法对考生的行为进行分析和识别&#xff0c;经过算法服务器的复杂计算和逻辑判断&#xff0c;算法将根据考生行为的特征和规律&#xff0c;判定是否存在作弊行为。…...

Python 操作 Redis 数据库介绍

Redis 作为常用的 NoSql 数据库&#xff0c;主要用于缓存数据&#xff0c;提高数据读取效率&#xff0c;那在 Python 中应该如果连接和操作 Redis 呢&#xff1f;今天就为大概简单介绍下&#xff0c;在 Python 中操作 Redis 常用命令。 安装 redis 首先还是需要先安装 redis …...

十年JAVA搬砖路——软件工程概述

软件工程是一门关注软件开发过程的学科&#xff0c;它涉及到软件的设计、开发、测试、部署和维护等方面。软件工程的目标是通过系统化的方法和工具&#xff0c;以确保软件项目能够按时、按预算和按要求完成。 • 软件工程的7个基本概念&#xff1a; 软件生命周期&#xff1a;软…...

前后端项目部署上线详细笔记

部署 参考文章&#xff1a;如何部署网站&#xff1f;来比比谁的方法多 - 哔哩哔哩大家好&#xff0c;我是鱼皮&#xff0c;不知道朋友们有没有试着部署过自己开发的网站呢&#xff1f;其实部署网站非常简单&#xff0c;而且有非常多的花样。这篇文章就给大家分享几种主流的前端…...

Android 蓝牙开发( 二 )

前言 上一篇文章给大家分享了Android蓝牙的基础知识和基础用法&#xff0c;不过上一篇都是一些零散碎片化的程序&#xff0c;这一篇给大家分享Android蓝牙开发实战项目的初步使用 效果演示 : Android蓝牙搜索&#xff0c;配对&#xff0c;连接&#xff0c;通信 Android蓝牙实…...

C#调用barTender打印标签示例

使用的电脑需要先安装BarTender 我封装成一个类 using System; using System.Windows.Forms;namespace FT_Tools {public class SysContext{public static BarTender.Application btapp new BarTender.Application();public static BarTender.Format btFormat;public void Q…...

Spring——Spring读取文件

文章目录 1.通过 value 读取比较简单的配置信息2.通过ConfigurationProperties读取并与 bean 绑定3.通过ConfigurationProperties读取并校验4. PropertySource 读取指定 properties 文件5.题外话:Spring加载配置文件的优先级 很多时候我们需要将一些常用的配置信息比如阿里云os…...

这是一条求助贴(postman测试的时候一直是404)

看到这个问题是404的时候总感觉不该求助大家&#xff0c;404多常见一看就是简单的路径问题&#xff0c;我的好像不是&#xff0c;我把我的问题奉上。 首先我先给出我的url http://10.3.22.195:8080/escloud/rest/escloud_contentws/permissionStatistics/jc-haojl/sz 这是我…...

信号完整性分析基础知识之有损传输线、上升时间衰减和材料特性(四):有损传输线建模

传输线中信号衰减的两个损耗过程是通过信号和返回路径导体的串联电阻以及通过有损耗介电材料的分流电阻。这两个电阻器的电阻都与频率相关。 值得注意的是&#xff0c;理想电阻器的电阻随频率恒定。我们已经证明&#xff0c;在理想的有损传输线中&#xff0c;用于描述损耗的两个…...

elk日志收集系统

目录 前言 一、概述 二、案例 &#xff08;一&#xff09;、环境配置 安装node1与node2节点的elasticsearch node1的elasticsearch-head插件 &#xff08;二&#xff09;、node1服务器安装logstash 测试1&#xff1a; 标准输入与输出 测试2&#xff1a;使用rubydebug解…...

perl 语言中 AUTOLOAD 的用法

这里的 AUTOLOAD可以理解为自动加载。具体来说就是&#xff0c;在正常情况下&#xff0c;我们不能调用一个尚未定义的函数&#xff08;子例程&#xff09;。不过&#xff0c;如果在未定义函数的包中有一个名为 AUTOLOAD的函数&#xff0c;那么对未定义函数的调用都会路由至这个…...

服务器放在香港好用吗?

​  相较于国内服务器&#xff0c;将网站托管在香港服务器上最直观的好处是备案层面上的。香港服务器上的网站无需备案&#xff0c;因此更无备案时限&#xff0c;购买之后即可使用。 带宽优势 香港服务器的带宽一般分为香港本地带宽和国际带宽、直连中国骨干网 CN2三种。香港…...

C++设计模式_01_设计模式简介(多态带来的便利;软件设计的目标:复用)

文章目录 本栏简介1. 什么是设计模式2. GOF 设计模式3. 从面向对象谈起4. 深入理解面向对象5. 软件设计固有的复杂性5.1 软件设计复杂性的根本原因5.2 如何解决复杂性 ? 6. 结构化 VS. 面向对象6.1 同一需求的分解写法6.1.1 Shape1.h6.1.2 MainForm1.cpp 6.2 同一需求的抽象的…...

Docker技术--WordPress博客系统部署初体验

如果使用的是传统的项目部署方式,你要部署WordPress博客系统,那么你需要装备一下的环境,才可以部署使用。 -1:操作系统linux -2:PHP5.6或者是更高版本环境 -3:MySQL数据环境 -4:Apache环境 但是如果使用Docker技术,那么就只需要进行如下的几行简单的指令: docker run …...

StarUML Java插件终极指南:高效实现UML与Java代码双向转换

StarUML Java插件终极指南&#xff1a;高效实现UML与Java代码双向转换 【免费下载链接】staruml-java Java extension for StarUML 项目地址: https://gitcode.com/gh_mirrors/st/staruml-java StarUML Java插件为Java开发者提供了强大的UML建模与代码生成能力&#xff…...

ReTerraForged终极指南:5个技巧打造专业级Minecraft地形生成

ReTerraForged终极指南&#xff1a;5个技巧打造专业级Minecraft地形生成 【免费下载链接】ReTerraForged TerraForged for modern MC versions 项目地址: https://gitcode.com/gh_mirrors/re/ReTerraForged ReTerraForged是一款专为Minecraft 1.19版本设计的革命性地形生…...

element-plus主题换色

提示&#xff1a;本篇暂未完善全&#xff0c;仅仅提供思路 具体的实现可以参考我这篇文章&#xff0c;验证可行&#xff1a;推荐使用该链接方式实现换色 主题方式是通过切换主题的方式实现换色&#xff0c;例如blue、green&#xff0c;不推荐&#xff0c;仅参考逻辑。 原因&a…...

Files.md:打造私密思考空间,兼具简洁实用与多样同步功能!

Files.md&#xff1a;专注思考的私密空间Files.md 是一款简洁的 .md 文件应用&#xff0c;为用户打造一个私密、安静的思考空间。用户可以用它存储生活中的一切&#xff0c;如笔记、文档、项目、日记、习惯记录、待办清单和任务等&#xff0c;所有内容都以纯 .md 文件形式保存&…...

如何选择Windows图片查看器?这款开源图像浏览器让你不再纠结

如何选择Windows图片查看器&#xff1f;这款开源图像浏览器让你不再纠结 【免费下载链接】ImageGlass &#x1f3de; A lightweight, versatile image viewer 项目地址: https://gitcode.com/gh_mirrors/im/ImageGlass 还在为Windows自带的图片查看器功能简陋而烦恼&…...

AI系统的四层缓存架构

别再被“提示词缓存”“语义缓存”绕晕了&#xff0c;它们根本不是一回事 先上关系图&#xff1a;AI系统里的四层缓存 很多人把缓存当一个东西聊&#xff0c;其实它们是四个不同的层&#xff0c;各管各的&#xff0c;又互相喂数据。 第一层 长期知识源 项目记忆缓存&#x…...

CANN/asc-devkit SIMT fmodf函数

fmodf 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言&#xff0c;原生支持C和C标准规范&#xff0c;主要由类库和语言扩展层构成&#xff0c;提供多层级API&#xff0c;满足多维场景算子开发诉求。 项目地址: https://gitcode.com/cann…...

如何5分钟快速上手Mayo:新手入门完全教程

如何5分钟快速上手Mayo&#xff1a;新手入门完全教程 【免费下载链接】mayo 3D CAD viewer and converter based on Qt OpenCascade 项目地址: https://gitcode.com/gh_mirrors/ma/mayo Mayo是一款基于Qt和OpenCascade开发的免费开源3D CAD查看器和转换器&#xff0c;支…...

深入STM32WLE5的LoRa核心:对比SX126x裸驱与LoRaWAN协议栈,哪个更适合你的项目?

STM32WLE5开发实战&#xff1a;裸驱与LoRaWAN协议栈的深度技术选型指南 当工程师面对STM32WLE5这颗集成了LoRa射频功能的跨界芯片时&#xff0c;第一个需要直面的灵魂拷问往往是&#xff1a;该用寄存器直接操作射频核心&#xff0c;还是拥抱现成的LoRaWAN协议栈&#xff1f;这个…...

阿里云ECS新手避坑指南:搞定校园网、安全组和SSH端口映射(附XShell连接测试)

阿里云ECS新手全流程配置手册&#xff1a;从安全组到SSH连接的深度实践 第一次接触云服务器时&#xff0c;那种既兴奋又忐忑的心情我至今记忆犹新。看着控制台里各种陌生的术语和选项&#xff0c;明明按照教程一步步操作却总是卡在连接阶段&#xff0c;这种经历想必不少技术爱好…...