23种设计模式之状态模式
目录
- 1. 简介
- 2. 代码
- 2.1 State (定义抽象状态接口)
- 2.2 StartState (实现具体状态类)
- 2.3 EndState (实现具体状态类)
- 2.4 Context (定义上下文类)
- 2.5 Test (测试类)
- 2.6 运行结果
- 3. 使用场景
- 4. 优缺点
- 5. 总结
1. 简介
状态模式(State Pattern) 是一种行为型设计模式,允许对象在其内部状态改变时改变其行为。这种模式通过将对象的状态和行为解耦,使得状态的变化不会直接影响对象的行为,从而提高了代码的可读性和可维护性。
状态模式主要由三个角色组成:
- 上下文(Context) :上下文类负责维护当前状态对象的引用,并提供对外接口,让客户端可以通过上下文与不同的状态对象进行交互。上下文类通常包含业务逻辑,这些逻辑会根据当前状态的不同而变化。
- 抽象状态(State) :抽象状态类定义了所有具体状态类共有的方法。这个类可以是一个接口或抽象类,用于声明状态更新的操作方法有哪些,具体实现由子类完成。
- 具体状态(Concrete State) :具体状态类继承抽象状态类,并实现具体状态下的行为逻辑。每个具体状态类对应一种状态的具体实现,处理与上下文相关的行为和状态转换。
2. 代码
2.1 State (定义抽象状态接口)
public interface State {public void doAction(Context context);
}
2.2 StartState (实现具体状态类)
public class StartState implements State{@Overridepublic void doAction(Context context){System.out.println("Player is in start state");context.setState(this);}public String toString(){return "Start State...";}
}
2.3 EndState (实现具体状态类)
public class EndState implements State{@Overridepublic void doAction(Context context){System.out.println("Player is in End State");context.setState(this);}public String toString(){return "End State...";}
}
2.4 Context (定义上下文类)
public class Context {private State state;public Context() {state = null;}public void setState(State state) {this.state = state;}public State getState() {return state;}
}
2.5 Test (测试类)
public class Test {public static void main(String[] args) {Context context = new Context();State state = new StartState();state.doAction(context);System.out.println(context.getState().toString());state = new EndState();state.doAction(context);System.out.println(context.getState().toString());}
}
2.6 运行结果
Player is in start state
Start State...
Player is in End State
End State...
3. 使用场景
几种场景:
对象的行为依赖于其状态:当一个对象的行为随着其内部状态的变化而变化时,可以使用状态模式。例如,在电子商务系统中,订单可能经历多种状态(如创建、支付、发货、完成和取消),每个状态下可以执行的操作不同,状态模式可以很好地管理这种状态的变化。
代码中包含大量的条件语句:当代码中包含大量的条件语句,并且这些条件语句表示对象的不同状态时,可以使用状态模式。状态模式可以将不同状态的处理分离出来,使得代码更加清晰。
对象的状态转换规则复杂:当对象的状态转换规则非常复杂时,可以使用状态模式。状态模式可以将状态转换规则封装在状态类中,使得状态转换更加灵活、可扩展。
需要增加新的状态:当需要增加新的状态时,可以使用状态模式。通过增加新的状态类,可以很容易地扩展状态模式。
对象具有多种状态且状态之间存在转换关系:当对象的行为随着其内部状态的变化而变化,并且这些状态之间存在复杂的转换逻辑时,状态模式非常有用。例如,在游戏编程中,可以根据游戏的不同阶段(如游戏开始、进行中、结束)来改变游戏逻辑。
并发编程中的线程状态管理:在并发编程中,可以根据线程的不同状态(如运行、等待、阻塞)来改变线程的行为。
图形用户界面(GUI)事件处理:在GUI开发中,可以根据用户界面的不同状态(如加载、成功、错误)来改变界面的行为。
银行系统中的账号状态管理:在银行系统中,可以根据账户的不同状态(如正常、冻结、注销)来管理账户的行为。
酒店系统中的房间状态管理:在酒店系统中,可以根据房间的不同状态(如已预订、已入住、空闲)来管理房间的使用情况。
TCP/IP网络连接中的状态管理:在TCP/IP网络连接中,可以根据连接的不同状态(如已建立、聆听、关闭)来处理不同的网络请求。
状态模式是一种非常实用的设计模式,它通过将对象的状态转换封装在状态类中,使得对象的状态转换更加灵活、可扩展,降低了对象的复杂度,提高了代码的可读性和可维护性。
4. 优缺点
优点:
- 结构清晰:状态模式将与特定状态相关的行为局部化到一个状态类中,使得代码结构更加清晰,易于理解和维护。
- 减少条件语句:通过使用状态模式,可以避免在代码中出现大量的条件判断语句(如switch-case或if-else),从而提高代码的可读性和简洁性。
- 符合开闭原则:状态模式允许在不修改现有代码的情况下添加新的状态,符合开闭原则,即对扩展开放,对修改关闭。
- 封装性好:状态的切换和行为变化被封装在类的内部实现,外部调用无需了解类内部如何实现状态和行为的变换。
- 易于扩展:增加新的状态只需增加新的状态类,而不需要修改现有代码,这使得系统具有良好的可维护性和可扩展性。
- 提高灵活性:状态模式支持动态地添加新的状态,无需修改现有代码,增强了系统的灵活性和可扩展性。
缺点:
- 类数量增加:每增加一种状态都需要创建一个新的状态类,这可能导致系统中类的数量显著增加,增加了系统的复杂性和管理难度。
- 复杂性增加:在一些简单的应用场景下,使用状态模式可能会引入不必要的复杂性,导致系统设计和代码维护的难度增加。
- 耦合性强:虽然状态模式将状态之间的行为分离,但状态之间的切换仍然存在一定的耦合关系,需要通过上下文类来进行状态的切换,可能会影响系统的灵活性。
- 过度设计:如果状态数量较少或状态转换逻辑简单,则使用状态模式可能会被认为是过度设计,反而降低代码的可读性。
5. 总结
无
相关文章:
23种设计模式之状态模式
目录 1. 简介2. 代码2.1 State (定义抽象状态接口)2.2 StartState (实现具体状态类)2.3 EndState (实现具体状态类)2.4 Context (定义上下文类)2.5 Test (测试类…...

Elasticsearch Serverless 中的数据流自动分片
作者:来自 Elastic Andrei Dan 在 Elastic Cloud Serverless 中,我们根据索引负载自动为数据流配置最佳分片数量,从而使用户无需摆弄分片。 传统上,用户会更改数据流的分片配置,以处理各种工作负载并充分利用可用资源。…...

YOLOv10改进,YOLOv10添加U-Netv2分割网络中SDI信息融合模块+GSConv卷积,助力小目标
理论介绍 完成本篇需要参考以下两篇文章,并已添加到YOLOv10代码中 YOLOv10改进,YOLOv10添加U-Netv2分割网络中SDI信息融合模块,助力小目标检测YOLOv10改进,YOLOv10添加GSConv卷积+Slim-neck,助力小目标检测,二次创新C2f结构下文都是手把手教程,跟着操作即可添加成功 目…...

xshell连接虚拟机,更换网络模式:NAT->桥接模式
NAT模式:虚拟机通过宿主机的网络访问外网。优点在于不需要手动配置IP地址和子网掩码,只要宿主机能够访问网络,虚拟机也能够访问。对外部网络而言,它看到的是宿主机的IP地址,而不是虚拟机的IP。但是,宿主机可…...
sql的where条件中使用case when
场景: 1、使用oracle数据库,数据类型为number,需要正无穷值。 2、数据表中有两个金额值,最大值和最小值, 如10~20, 30 ~40,40以上,数据库中这样设计 id name min max 1 j 10 20 2 …...
MacOS 上以源码形式安装 MySQL 5.7
以下是在 macOS 上从源码安装 MySQL 5.7 的步骤: 前置条件 安装 Homebrew:如果你还没有安装 Homebrew,可以在终端中运行以下命令进行安装: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install…...
MySQL 事务隔离级别详解
一、事务的基本概念 (一)什么是事务 事务是一个逻辑工作单元,由一组数据库操作组成。这些操作要么全部成功执行,要么全部回滚,以确保数据库的一致性。事务具有以下四个特性,通常被称为 ACID 特性ÿ…...

C语言——高精度问题
1、高精度计算的本质:竖式计算; 2、适用解决超出long long int 范围的大整数计算 #include<stdio.h> #include<string.h> #define N 100 char str1[N4]{0},str2[N4]{0}; int arr1[N4]{0},arr2[N4]{0}; int ans[N5]{0};//将字符串转化成整型…...

aippt:AI 智能生成 PPT 的开源项目
aippt:AI 智能生成 PPT 的开源项目 在现代办公和学习中,PPT(PowerPoint Presentation)是一种非常重要的展示工具。然而,制作一份高质量的PPT往往需要花费大量的时间和精力。为了解决这一问题,aippt项目应运…...

【Qt之·类QSettings·参数保存】
系列文章目录 文章目录 前言一、概述1.1 QSetting是什么1.2 为什么学习QSetting是重要的 二、不同存储位置的优缺点三、 QSetting的高级用法四、实例演示总结 前言 在当今的应用程序开发中,设置管理是一个至关重要的方面。应用程序的设置包括用户偏好、配置选项和其…...

location重定向和nginx代理
文章目录 1 location重定向1.1 概述1.2 rewrite跳转1.3 用例1.4 实验1.4.1 基于域名的跳转1.4.2 基于ip的跳转1.4.3 基于后缀名的跳转 2 nginx的代理2.1 nginx内置变量2.2 正向代理2.2.1 固定正向代理2.2.2 自动代理 2.3 反向代理2.3.1 负载均衡的算法2.3.2 负载均衡的特点2.3.…...

iptables详解
华子目录 什么是防火墙分类netfilter(数据包过滤)定义netfilter分析内容 防火墙无法完成的任务netfilter策略管理工具netfilter的5类hook函数防火墙规则策略匹配原则iptablesiptables流量处理动作iptables表5种规则表 安装iptablesiptables策略文件 ipta…...

Edge SCDN深度解析,边缘安全加速的创新实践
边缘安全加速(Edge Secure Content Delivery Network,SCDN)是酷盾安全推出的边缘集分布式 DDoS 防护、CC 防护、WAF 防护、BOT 行为分析为一体的安全加速解决方案。通过边缘缓存技术,智能调度使用户就近获取所需内容,为…...

solidworks常见问题已解决
solidworks常见问题已解决 问题1:step总是提示默认模板无效。问题2:异型孔向导”时出现了“找不到标准数据库。问题3:找不到CalloutForm.txt文件,标注将由几何体定义。问题5:工程图显示文件损坏不能保存。问题6&#x…...

vCenter开启HA报错
昨天给客户开启vCenter开启HA功能报错,报错的内容比较多 博通官方给出解决办法 https://knowledge.broadcom.com/external/article/318929/error-vsphere-ha-agent-cannot-be-correct.html 常规的解决办法 1.关闭集群HA,再次开启HA 2.主机进入维护模式,再次加入…...

在 Ubuntu 中 make 是否是系统自带的?怎么样查看Linux系统中是否有make?
make 命令 并不是所有 Ubuntu 系统都默认安装的,但它通常是开发工具链的一部分,许多开发者会在安装系统后配置它。make 是一个非常重要的构建工具,用于自动化编译和构建过程,特别是在编译软件或内核时。 make 的来源 make 是一个…...

js:我要在template中v-for循环遍历这个centrerTopdata,我希望自循环前面三个就可以了怎么写
问: 我按在要在template中v-for循环遍历这个centrerTopdata,我希望自循环前面三个就可以了怎么写? 回答: 问: <div v-for"(item, index) in centrerTopdata.slice(0, 3)" :key"index"> d…...

前端使用 Cursor 的最佳助手 - PromptCoder
前端使用 Cursor 的最佳助手 - PromptCoder 你是否正在使用 Cursor 进行前端开发,却苦于繁琐的代码生成和原型图的还原?你是否渴望一个更高效、更智能的工具来提升你的开发效率?那么,你一定不能错过 PromptCoder! Pr…...

深入了解 Spring IOC,AOP 两大核心思想
文章目录 一、Spring 基础 - 控制反转(IOC)1.1. 引入1.2. 如何理解 IOCSpring Bean 是什么?IoC 是什么?IoC 能做什么?IoC 和 DI 是什么关系? 1.3. IoC 配置的三种方式xml 配置Java 配置注解配置 1.4. 依赖注…...

QT从入门到精通——Qlabel介绍与使用
1. QT介绍——代码测试 Qt 是一个跨平台的应用程序开发框架,广泛用于开发图形用户界面(GUI)应用程序,也支持非图形应用程序的开发。Qt 提供了一套工具和库,使得开发者能够高效地构建高性能、可移植的应用程序。以下是…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...