设计模式二十一:状态模式(State Pattern)
一个对象的内部状态发生变化时,允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类,主要目的是将状态的行为从主要对象中分离出来,使得主要对象不必包含所有状态的逻辑,而是将每个状态的行为封装在独立的类中。这有助于减少代码的重复,提高代码的可维护性和可扩展性。
状态模式的使用场景
- 对象的行为随着其内部状态的改变而改变
如果一个对象的行为取决于其内部的状态,并且在运行时可能会频繁地改变状态,那么状态模式可以使得对象的行为更加灵活和易于管理。 - 对象有多个状态,每个状态有不同的行为
当一个对象具有多个状态,并且不同状态下有不同的行为时,状态模式可以帮助将这些不同的行为分离到不同的状态类中,从而保持代码的清晰度和可维护性。 - 避免条件语句的过多嵌套
状态模式可以减少代码中的条件语句嵌套,使代码更加易读,更易于扩展和维护。 - 状态转换的规则复杂且多变
如果对象的状态转换规则非常复杂,可能会随着需求的变化而频繁修改,那么状态模式可以将状态转换逻辑集中到具体的状态类中,减少对主要对象的影响。 - 对象的状态可以在运行时动态改变
状态模式允许对象在运行时切换状态,而且可以相对容易地添加新的状态类。 - 避免在主要对象中堆积大量的条件逻辑
使用状态模式可以将每个状态的逻辑封装在独立的状态类中,避免在主要对象中堆积大量的状态相关的条件逻辑。
状态模式的主要角色
状态模式涉及三个主要角色:Context(上下文)、State(状态)、ConcreteState(具体状态)。状态模式的基本思想是将对象的状态封装成独立的状态类,使得对象的行为可以根据其状态的变化而改变。Context对象通过委托当前状态的行为,实现了在不同状态下的不同行为。
在使用状态模式时,Context对象通常会持有一个当前状态的引用,该引用会在运行时改变。当Context的行为需要根据状态变化而变化时,它会调用当前状态对象的方法,从而实现相应的行为。状态对象之间的切换可以在Context内部进行,或者由外部控制
- Context(上下文)
Context是拥有状态的对象,它维护一个指向当前状态的引用。在状态模式中,Context的行为会随着其内部状态的改变而改变。Context类在使用状态模式时负责将请求委托给当前状态对象。它也可以提供一些方法来允许状态对象改变Context的当前状态。 - State(状态)
State是一个抽象类或接口,定义了具体状态类需要实现的方法。这些方法代表了在特定状态下对象可能执行的行为。Context通过调用这些方法来委托实际的行为给当前状态对象。 - ConcreteState(具体状态)
具体状态类是State的子类,实现了State接口中定义的方法。每个具体状态类都代表Context在特定状态下的行为。通过具体状态类,可以封装和维护特定状态下的行为逻辑。
状态模式java代码实例
假设我们有一个文档编辑器,可以处于三种状态:编辑状态、只读状态和锁定状态。每种状态下,文档编辑器的行为不同。
State接口
public interface EditorState {void type(String content);
}
具体状态
public class EditingState implements EditorState{@Overridepublic void type(String content) {System.out.println("当前处于编辑状态,编辑中......"+content);}}public class LockedState implements EditorState{@Overridepublic void type(String content) {System.out.println("当前处于锁定状态,无法编辑");}
}public class ReadOnlyState implements EditorState{@Overridepublic void type(String content) {System.out.println("当前处于仅阅读状态,无法编辑");}
}
上下文
public class Editor {private EditorState currentState;public Editor() {this.currentState = new EditingState(); // 初始状态为编辑状态}public void setState(EditorState state) {this.currentState = state;}public void type(String content) {currentState.type(content);}
}
客户端
public class State {public static void main(String[] args) {Editor editor = new Editor();editor.type("七夕快乐!");editor.setState(new ReadOnlyState());editor.type("七夕快乐!");editor.setState(new LockedState());editor.type("七夕快乐!");}}
输出
当前处于编辑状态,编辑中......七夕快乐!
当前处于仅阅读状态,无法编辑
当前处于锁定状态,无法编辑
状态模式的优缺点
状态模式作为一种设计模式,具有一些优点和缺点,下面是它们的总结:
优点:
- 清晰的状态管理:状态模式将不同状态的行为封装在独立的状态类中,使得状态之间的转换变得清晰,减少了代码的混乱和重复。
- 可维护性和扩展性:由于每个状态都是一个独立的类,当需要添加新的状态时,只需要新增一个状态类,而不需要修改现有的代码。这有助于提高系统的可维护性和可扩展性。
- 消除大量的条件语句:状态模式可以消除大量的条件语句,从而使代码更加简洁和易于理解。状态切换的逻辑被封装在状态类内部,避免了在主要对象中堆积复杂的条件判断。
- 符合开闭原则:添加新的状态类不会影响到已有的代码,符合开闭原则,即对扩展开放,对修改关闭。
缺点:
- 增加了类的数量:引入状态模式会增加系统中的类的数量,尤其在状态较多时,可能会导致类的数量过多,增加代码量。
- 可能引起混乱:当状态较多时,可能会增加代码的复杂性,需要仔细管理状态之间的转换逻辑,以避免出现混乱。
- 不适用于简单情况:对于仅有几种状态且状态转换逻辑简单的情况,引入状态模式可能会过于复杂,不切实际。
- 态之间的耦合:虽然状态模式将状态之间的行为分离,但状态之间的切换仍然存在一定的耦合,需要通过Context类来进行状态的切换,可能会影响一定的灵活性。
相关文章:
设计模式二十一:状态模式(State Pattern)
一个对象的内部状态发生变化时,允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类,主要目的是将状态的行为从主要对象中分离出来,使得主要对象不必包含所有状态的逻辑,而是将每个状态的行为封装在独立的类…...

【校招VIP】产品思维能力之产品设计
考点介绍: 对于产品经理来说最重要的就是产品思维,而拥有一个好的产品思维需要做到以下三点: 1、把握关键点的能力 2、出方案,协调资源,说服团队把资源倾斜到关键点上的能力 3、评估关键点进展程度的能力 『产品思维能…...

微信小程序卡片横向滚动竖图
滚动并不是使用swiper,该方式使用的是scroll-view实现 Swiper局限性太多了,对竖图并不合适 从左往右滚动图片示例 wxml代码: <view class"img-x" style"margin-top: 10px;"><view style"margin: 20rpx;…...

SpringBoot项目(支付宝整合)——springboot整合支付宝沙箱支付 从极简实现到IOC改进
目录 引出git代码仓库准备工作支付宝沙箱api内网穿透 [natapp.cn](https://natapp.cn/#download) springboot整合—极简实现版1.导包配置文件2.controller层代码3.进行支付流程4.支付成功回调 依赖注入的改进1.整体结构2.pom.xml文件依赖3.配置文件4.配置类,依赖注入…...

【AIGC】一款离线版的AI智能换脸工具V2.0分享(支持图片、视频、直播)
随着人工智能技术的爆发,AI不再局限于大语言模型,在图片处理方面也有非常大的进步,其中AI换脸也是大家一直比较感兴趣的,但这个技术的应用一直有很大的争议。 今天给大家分享一个开源你的AI换脸工具2.0,只需要一张所需…...
管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容选言——或
文章目录 第五章 选言命题:相容选言-或;不相容选言-要么要么第一节 选言-相容选言-或-推结论-A或B为真,则非A→B,非B→A(否一则肯一)真题(2010-28)-选言-相容选言-或-推结论-(1)A或B为真,A为假:得B为真(否一则肯一);真题(2012-29)-选言-相容选言-或-推结论-(1)…...

Git如何操作本地分支仓库?
基本使用TortoiseGit 操作本地仓库(分支) 分支的概念 几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来,避免影响开发主线。多线程开发,可以同时开启多个任务的开发,多个任务之间互不影响。 为何要…...

WPS右键新建没有docx pptx xlsx 修复
解决wps右键没有新建文档的问题 右键没有新建PPT和Excel 1 wps自带的修复直接修复没有用 以上不管咋修复都没用 2 先编辑注册表 找到 HKEY_CLASSES_ROOT CTRLF搜文件扩展名 pptx docx xlsx 新建字符串 三种扩展名都一样操作 注册表编辑之后再次使用wps修复 注册组件&am…...

【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“
文章目录 前言🌟一、函数重载🌏1.1.函数重载概念🌏1.2.C支持函数重载的原理 -- 名字修饰 🌟二、引用🌏2.1.引用的概念🌏2.2.引用特性🌏2.3.常引用🌏2.4.使用场景🌏2.5.传…...
【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)
【关键字】 音频编码、管道模式、createEncoder 【写在前面】 在使用API6开发HarmonyOS应用时,如何将pcm源文件进行编码并写入文件,最后生成aac文件,本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】 import ohos.media.codec.…...

KaiwuDB CTO 魏可伟:回归用户本位,打造“小而全”的数据库
8月16日,KaiwuDB 受邀亮相第十四届中国数据库技术大会 DTCC 2023。KaiwuDB CTO 魏可伟接受大会主办方的采访,双方共同围绕“数据库架构演进、内核引擎设计以及不同技术路线”展开深度探讨。 以下是采访的部分实录 ↓↓↓ 40 多年前,企业的数…...

行业追踪,2023-08-22
自动复盘 2023-08-22 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...

浏览器安装selenium驱动,以Microsoft Edge安装驱动为例
Selenium是一个用于Web应用程序测试的自动化工具。它可以直接在浏览器中运行,模拟真实用户对浏览器进行操作。利用selenium,可以驱动浏览器执行特定的动作,比如:点击、下拉等等,还可以获取浏览器当前呈现的页面的源代码…...

边缘计算网关是如何提高物联网的效率的?
随着物联网的持续发展,物联网应用的丰富和规模的扩大,带来了海量的数据处理、传输和计算需求。 传统的“数据中央处理”模式越来越难以适应物联网的扩展速度,在这一趋势下,边缘计算在物联网系统的部署运营中就发挥出了显著的增效…...

AWVS安装~Windows~激活
目录 1.下载安装包 2.双击acunetix_15.1.221109177.exe进行安装 3.配置C:\Windows\System32\drivers\etc\hosts 4.复制wvsc.exe到C:\Program Files (x86)\Acunetix\15.1.221109177下 5.复制license_info.json与wa_data.dat到C:\ProgramData\Acunetix\shared\license下&…...
ATFX汇市:杰克逊霍尔年会降至,鲍威尔或再发鹰派言论
环球汇市行情摘要—— 昨日,美元指数下跌0.11%,收盘在103.33点, 欧元升值0.22%,收盘价1.0898点; 日元贬值0.58%,收盘价146.23点; 英镑升值0.18%,收盘价1.2757点; 瑞…...
Zipkin开源的分布式链路追踪系统
Zipkin是一款开源的分布式链路追踪系统,主要功能包括: 1. 采集跟踪数据 - Zipkin client库负责收集并上报各服务的请求信息。 2. 存储跟踪数据 - 存储层默认采用Zipkin自带的基于内存的快速存储,也支持整合MySQL、Cassandra等外部存储。 3. 查询接口 - 提供RESTful API进行跟…...

java 项目运行时,后端控制台出现空指针异常---java.lang.NullPointerException
项目场景: 提示:这里简述项目背景: 场景如下: java 项目运行时,后端控制台出现如下图所示报错信息:— 问题描述 提示:这里描述项目中遇到的问题: java 项目运行时,后…...

模型数据处理-数据放入 session和@ModelAttribute 实现 prepare 方法详细讲解
😀前言 本文详细讲解了模型数据处理-数据放入 session和ModelAttribute 实现 prepare 方法详细讲解 🏠个人主页:尘觉主页 🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,…...

关于android studio 几个简单的问题说明
自信是成功的第一步。——爱迪生 1. android studio 如何运行不同项目是否要更换不同的sdk 和 gradle 2.编译Gradle总是错误为什么 3.如何清理android studio 的缓存 4. 关于android Studio中的build 下面的rebuild project...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...