【设计模式深度剖析】【10】【行为型】【状态模式】
👈️上一篇:访问者模式 | 下一篇:解释器模式👉️
设计模式-专栏👈️
文章目录
- 状态模式
- 定义
- 英文定义
- 直译
- 如何理解呢?
- 状态模式的角色
- Context(环境类)
- State(抽象状态类)
- ConcreteState(具体状态类)
- 类图
- 代码示例
- 状态模式的应用
- 优点
- 缺点
- 使用场景
状态模式
状态模式(State Pattern)又称为状态对象(Objects for States)模式,该模式允许一个对象在其内部状态改变时改变其行为。
状态模式就像一部智能的“剧情播放器”,根据不同的“剧本”(状态)自动切换“演员”(行为),让系统“表演”出各种复杂且有序的行为。
定义
英文定义
The State Pattern allows an object to alter its behavior when its internal state changes. The object will appear to change its class.
直译
状态模式允许一个对象在其内部状态改变时改变其行为。这个对象看起来像是改变了它的类。
如何理解呢?
状态模式就像是一个智能的“状态机”,它可以管理一个对象的多种状态,并根据当前状态来执行相应的行为。
比如,我们可以把一个电梯看作是一个对象,它有三种状态:停止、运行和故障。
当电梯处于不同的状态时,它的行为也会不同。
例如,
当电梯处于停止状态时,它不会移动;
当电梯处于运行状态时,它可以响应乘客的上下行请求;
当电梯出现故障时,它会停止运行并发出警报。
通过使用状态模式,我们可以将这些状态和对应的行为封装在单独的类中,使得代码更加清晰和易于维护。
同时,当需要添加新的状态或修改某个状态的行为时,我们只需要修改对应的状态类,而不需要修改其他部分的代码,这使得系统具有很好的扩展性和可维护性。
当控制一个对象状态的条件表达式过于复杂时,状态模式可以将这些复杂的判断逻辑转移到表示不同状态的一系列类中,从而简化判断逻辑。
状态模式的角色
Context(环境类)
也称为上下文,它定义了客户端所感兴趣的接口,并且维护一个具体状态对象的实例。这个实例定义了当前状态。
State(抽象状态类)
这是一个抽象类或接口,用以封装与Context的一个特定状态相关的行为。
ConcreteState(具体状态类)
这是实现了State接口的类,每一个类实现了一个与Context的一个状态相关的行为。
类图
代码示例
package com.polaris.designpattern.list3.behavioral.pattern10.state.classicdemo;// 抽象状态类
interface State {void handleRequest(Context context);
}// 具体状态类A
class StateA implements State {@Overridepublic void handleRequest(Context context) {System.out.println("StateA handling request");// 假设在StateA处理请求后,无条件地转移到StateB context.setState(new StateB());}
}// 具体状态类B
class StateB implements State {@Overridepublic void handleRequest(Context context) {System.out.println("StateB handling request");// 假设在StateB处理请求后,根据某个条件判断是否转回StateA if (someConditionToCheck()) { // 这是一个假设的条件检查方法 context.setState(new StateA());System.out.println("State changed to A");} else {System.out.println("Remaining in State B");}}// 假设的条件检查方法 private boolean someConditionToCheck() {// 这里可以添加你的条件逻辑 // 例如,可以检查某个变量的值,或者模拟用户输入等 // 这里我们简单地返回一个固定值作为示例 return Math.random() < 0.5; // 50% 的概率返回 true }
}// 环境类
class Context {private State state;public Context() {// 初始状态设置为StateA this.state = new StateA();}public void setState(State state) {this.state = state;}public void request() {// 委托给当前状态对象处理请求 state.handleRequest(this);}// Getter方法用于调试或日志记录(可选) public State getState() {return state;}
}// 客户端代码
public class Client {public static void main(String[] args) {Context context = new Context();// 客户端发送请求给Context context.request(); // 输出 "StateA handling request",并转移到StateB // 假设这里有一些业务逻辑,但这里没有额外的代码 // 再次发送请求以展示可能的状态变化 context.request(); // 输出 "StateB handling request",并根据条件判断是否转回StateA // 第三次发送请求,以展示状态可能继续变化或保持不变 context.request(); // 输出将取决于StateB中的条件判断 // (可选)打印当前状态用于调试或日志记录 System.out.println("Current state: " + context.getState().getClass().getSimpleName());}
}/* Output:
StateA handling request
StateB handling request
State changed to A
StateA handling request
Current state: StateB
*///~
在上面的示例中,
Context
类代表了一个对象,它的行为可能会根据当前的状态(State
)而变化。每个ConcreteState
(这里是StateA
和StateB
)都定义了在该状态下如何处理请求。当Context
收到一个请求时,它会将请求委托给当前的状态对象去处理。状态对象在处理请求时,可能会改变Context
的状态。
状态模式的应用
状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。简单来说,就是当某个对象有多种状态,并且不同状态下有不同的行为时,我们可以使用状态模式来管理这些状态和对应的行为。
优点
- 封装了状态的转换规则:状态模式将状态的转换逻辑封装在状态类中,使得代码更加清晰和易于管理。
- 简化条件语句:避免了使用大量的条件语句来判断对象的状态和行为,使得代码更加简洁和易于维护。
- 可维护性高:当需要添加新的状态或修改某个状态的行为时,只需要修改对应的状态类,而不需要修改其他部分的代码,符合开闭原则。
- 扩展性好:状态模式允许新的状态类很容易地加入到系统中,使得系统具有很好的扩展性。
缺点
- 增加系统复杂性:使用状态模式会增加系统中类和对象的个数,使得系统结构变得复杂。
- 对开闭原则的支持不足:虽然状态模式在一定程度上符合开闭原则,但当需要添加新的状态时,可能需要修改状态转换的代码,这可能会破坏开闭原则。
- 使用不当可能导致代码混乱:如果状态模式和具体业务逻辑结合不当,可能会导致代码结构混乱,增加维护难度。
使用场景
- 对象的行为取决于它的状态:当对象的行为会根据其内部状态的不同而发生变化时,可以使用状态模式。
- 状态转换逻辑复杂:当对象的状态转换逻辑非常复杂时,使用状态模式可以将这些逻辑封装在状态类中,使得代码更加清晰和易于维护。
- 避免使用大量的条件语句:当代码中使用了大量的条件语句来判断对象的状态和行为时,可以考虑使用状态模式来简化代码。
👈️上一篇:访问者模式 | 下一篇:解释器模式👉️
设计模式-专栏👈️
相关文章:
【设计模式深度剖析】【10】【行为型】【状态模式】
👈️上一篇:访问者模式 | 下一篇:解释器模式👉️ 设计模式-专栏👈️ 文章目录 状态模式定义英文定义直译如何理解呢? 状态模式的角色Context(环境类)State(抽象状态类)Concret…...
API低代码平台介绍5-数据库记录修改功能
数据库记录修改功能 在上篇文章中我们介绍了如何插入数据库记录,本篇文章会沿用上篇文章的测试数据,介绍如何使用ADI平台定义一个修改目标数据库记录的接口,包括 单主键单表修改、复合主键单表修改、多表修改(整合前两者ÿ…...
git commit撤销修改
背景 如果提交了代码,却发现有不需要提交的文件。这时候如何修改呢?可以用git reset指令。 git reset用法解释 git reset 命令用于回退版本,可以指定退回某一次提交的版本。 git reset 命令语法格式如下: git reset [--soft …...
深入理解RunLoop
RunLoop 是 iOS 和 OSX 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理。之后会介绍一下在 iOS 中,苹果是如何利用 RunLoop 实现自动释放池、延迟回调、触摸事件、屏幕刷新等功能的。 一…...
Elasticsearch term 查询:精确值搜索
一、引言 Elasticsearch 是一个功能强大的搜索引擎,它支持全文搜索、结构化搜索等多种搜索方式。在结构化搜索中,term 查询是一种常用的查询方式,用于在索引中查找与指定值完全匹配的文档。本文将详细介绍 term 查询的工作原理、使用场景以及…...
IntelliJ IDEA调试技巧
IntelliJ IDEA高级调试技巧 假设我们在UserService类的getUserAndCheckStatus方法中遇到了难以追踪的问题。以下是在IntelliJ IDEA中进行高效调试的一些进阶技巧: 1. 条件断点(Conditional Breakpoint) 如果你知道问题只在特定条件下出现&…...
NGINX_六 nginx 日志文件详解
六 nginx 日志文件详解 nginx 日志文件分为 **log_format** 和 **access_log** 两部分log_format 定义记录的格式,其语法格式为log_format 样式名称 样式详情配置文件中默认有log_format main $remote_addr - $remote_user [time_local] "req…...
第6章 工程项目融资 作业
第6章 工程项目融资 作业 一单选题(共2题,40分) (单选题) 项目资金结构不包括( )。 A.项目债务资金结构比例 B. 项目建设投资与工程项目总成本费用的比例 C. 项目资本金内部结构比例 D. 项目资本金与债务资金的比例 正…...
网站安全防护怎么做?
引言:在当今数字化的时代,网络安全已经成为个人、企业乃至整个社会的一项关键挑战。随着互联网的普及和信息技术的迅猛发展,我们的生活和工作方式日益依赖于各种互联网服务和数据交换。然而,这种依赖也带来了越来越多的安全威胁和…...
泵设备的监测控制和智慧运维
泵是一种输送流体或使流体增压的机械。它通过各种工作原理(如离心、柱塞等)将机械能转换为流体的动能或压力能,从而实现液体的输送、提升、循环等操作。 泵的一些具体应用场景: 1.智能水务:在城市供水管网中ÿ…...
【智能算法应用】基于混合粒子群-蚁群算法的多机器人多点送餐路径规划问题
目录 1.算法原理2.数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】粒子群算法(PSO)原理及实现 配餐顺序: 采用混合粒子群算法 || 路径规划: 采用蚁群算法 2.数学模型 餐厅送餐多机器人多点配送路径规划&…...
Java中的JVM调优技巧
Java中的JVM调优技巧 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! Java虚拟机(JVM)是Java应用程序的核心组件,负责将Jav…...
软件工程-第4章结构化编码和测试
软件的实现阶段:软件编码,单元测试和综合测试。 软件编码是对软件设计的进一步具体化,其任务是将设计表示变换成用程序设计语言编写的程序。 软件测试是软件质量保证的重要手段,要成功开发出高质量的软件产品,必须认…...
MMDetection 目标检测 —— 环境搭建和基础使用
参考文档 开始你的第一步 — MMDetection 3.3.0 文档 依赖 步骤 0. 下载并安装 Anaconda。 步骤 1. 创建并激活一个 conda 环境。(我选择的是python3.10) conda create --name openmmlab python3.8 -y conda activate openmmlab 步骤 2. 基于 PyTo…...
C# 实现draw一个简单的温度计
运行结果 概述: 代码分析 该控件主要包含以下几个部分: 属性定义: MinValue:最低温度值。 MaxValue:最高温度值。 CurrentValue:当前温度值。 构造函数: 设置了一些控件样式来提升绘制效果…...
解放双手,让流程自动化软件助你一臂之力
本文将介绍流程自动化软件/脚本/助手的用途,同时我也做个自我介绍: 🏆 技术专长:专注于自动化脚本、网站、小程序、软件、爬虫及数据采集的定制化开发,为客户提供全方位的数字化解决方案。 💼 行业经验&…...
邀请函 | 桥田智能出席AMTS展会 家族新成员正式发布
作为国际汽车制造技术与装备及材料专业展览会,AMTS将于2024年7月3-5日在上海新国际博览中心举行。本届展会以【向“新”而行 “智”领未来】为主题,聚焦汽车及新能源全产业链,围绕“车身工程、部件工程、新能源三电工程及未来汽车开发”等技…...
安卓开发使用proxyman监控真机
1、真机跟电脑连接到同个网络中 2、手机里面设置代理,代理地址为proxyman上面指示的地址。 3、一般情况下,电脑的对应的端口是没开放的。需要到防火墙里面新建规则。入站规则 选择端口输入上方端口号 这样就能监控到了...
ruoyi登录功能源码分析
Ruoyi登录功能源码分析 上一篇文章我们分析了一下若依登录验证码生成的代码,今天我们来分析一下登录功能的代码 1、发送登录请求 前端通过http://localhost/dev-api/login向后端发送登录请求并携带用户的登录表单 在后端中的com.ruoyi.web.controller.system包下…...
推动产业数字化转型,六个方面引领变革
从工业经济时代走向数字经济时代,世界经济发生着全方位、革命性的变化,产业数字化便是最显著的表现之一。当前,产业数字化不断深入发展,平台经济、工业互联网、智能制造等新业态、新模式不断涌现,成为了数字经济的重要…...
设施布置之车间布局优化SLP分析
一 物流分析(Flow Analysis) 的基本方法 1、当物料移动是工艺过程的主要部分时,物流分析就是工厂布置设计的核心工作,也是物料搬运分析的开始。 2、零部件物流是该部件在工厂内移动时所走过的路线, 物流分析不仅要考虑…...
帕金森的锻炼方式
帕金森病,这个看似陌生的名词,其实离我们并不遥远。它是一种常见的神经系统疾病,影响着许多中老年人的生活质量。虽然帕金森病目前尚无根治之法,但通过科学合理的日常锻炼,可以有效缓解病情,提高生活质量。…...
PyTorch(一)模型训练过程
PyTorch(一)模型训练过程 #c 总结 实践总结 该实践从「数据处理」开始到最后利用训练好的「模型」预测,感受到了整个模型的训练过程。其中也有部分知识点,例如定义神经网络,只是初步的模仿,有一个比较浅的…...
windows下cmd命令行模式中cd变换路径命令无效的解决办法
一,出现的情况 二,解决方法 当出现转换盘的时候打开 cmd 之后可能是无法生效的 ,因为在cmd 中转换盘首先需要用到换盘符 。 Solve1 : 先进行换盘 C: c: // 转换到 C盘 D: d: // 转化到 D盘 Solve2 : 直接进行强转 cd /dE:\ACM算法资源\XCP…...
收藏||电商数据采集流程||电商数据采集API接口
商务数据分析的流程 第一步:明确分析目的。首先要明确分析目的,并把分析目的分解成若干个不同的分析要点,然后梳理分析思路,最后搭建分析框架。 第二步:数据采集。主流电商API接口数据采集,一般可以通过数…...
修改源码,打patch包,线上环境不生效
1.首先看修改的源码文件是否正确 在node_modules中,找对应的包,然后查看包中package.json 的main和module。如果用require引入,则修改lib下面的组件,如果是import引入则修改es下面的文件 main 对应commonjs引入方式的程序入口文件…...
NUC980-OLED实现全中文字库的方法
1.背景 有一个产品,客户需要屏幕展示一些内容,要带一些中文,实现了OLED12864的驱动,但是它不带字库,现在要实现OLED全字库的显示 2.制作原始字库 下载软件pctolcd2002 设置 制作字库 打开原始文件 用软件自带的&…...
UEFI 启动原理及qemu 虚拟化中使用
UEFI 启动原理及qemu 虚拟化中使用 什么是BIOS?什么是 UEFI? 什么是BIOS? 计算机启动时会加载 BIOS,以初始化和测试硬件功能。它使用 POST 或 Power On Self Test 来确保硬件配置有效且工作正常,然后寻找存储引导设…...
35、正则表达式
一、正则表达式命令 正则表达式:匹配的是文本内容,linux的文本三剑客都是针对文本内容。 grep 过滤文本内容 sed 针对文本内容进行增删改查 awk 按行取列 文本三剑客----都是按照行进行匹配。 1.1、grep筛选: grep的作用就是…...
Ubuntu20.04中复现FoundationPose
Ubuntu20.04中复现FoundationPose 文章目录 Ubuntu20.04中复现FoundationPose1.安装cuda和cudnn2.下载相关资源3.环境配置4.运行model-based demo5.运行ycbv demoReference 🚀 非常重要的环境配置 🚀 ubuntu 20.04cuda 11.8.0cudnn v8.9.7python 3.9.19…...
衡水做网站推广/商品标题优化
参考:https://www.jb51.net/article/165467.htm 新建一个PyQt demo,创建一个项目 如下图 如下图打开QtDesigner 打开Qt界面如下图 如图选择创建一个Main Window 如图可以根据需要添加自己的组件 如下图保存 如下图,使用PyUIC将hello.ui文件转换为…...
辽宁城乡住房建设厅网站打不开/百度官网
Linux(18)——Vsftp&Selinux - Vsftp VSFTP 1. Vsftp 信息 VSFTP是一个类Unix系统上使用的FTP服务器软件,全称Very Secure FTP 。 服务名称: vsftpd.service配置目录: /etc/vsftpd 主配置文件: /etc/vsftpd/vsftpd.conf 默认发布目录: /var/ftp报错信息&…...
万网站建设/网站外链购买平台
第 1 章:Web基础技术作者:党海峰,孙霞 来源:希赛网 2014年03月14日 HTTP请求消息 HTTP请求消息由Request-Line(请求行)、Header Field(头域)和Message-Body(消息体…...
四方坪网站建设/东莞网站建设最牛
转载:http://www.cnblogs.com/woider/p/5926744.html pymysql 由于 MySQLdb 模块还不支持 Python3.x,所以 Python3.x 如果想连接MySQL需要安装 pymysql 模块。 pymysql 模块可以通过 pip 安装。但如果你使用的是 pycharm IDE,则可以使用 proj…...
梦幻创意晋城网站建设/互联网运营自学课程
function countCharacters(str, num) {var str str || ,num num || 0,res ,length 0;if (!str || !num) {return str;}// 循环字符串,判断长度 最少也会返回一个字for (var i in str) {res str[i];// 测试长度length /[\u4e00-\u9fa5]/.test(str[i]) ? 2 :…...
武汉网站制作公司选华企加速器/成都网站优化
1. 描述 单元格是组成报表的最小元素,FineReport 将单元格很多属性开放给应用开发人员进行控制,如新增单元格,设置列宽、行高,字体、前景色,背景色、显示位置、边框样式、边框颜色等等。 以下我们将常用的属性设置列…...