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

设计模式二十一:状态模式(State Pattern)

一个对象的内部状态发生变化时,允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类,主要目的是将状态的行为从主要对象中分离出来,使得主要对象不必包含所有状态的逻辑,而是将每个状态的行为封装在独立的类中。这有助于减少代码的重复,提高代码的可维护性和可扩展性。

状态模式的使用场景

  1. 对象的行为随着其内部状态的改变而改变
    如果一个对象的行为取决于其内部的状态,并且在运行时可能会频繁地改变状态,那么状态模式可以使得对象的行为更加灵活和易于管理。
  2. 对象有多个状态,每个状态有不同的行为
    当一个对象具有多个状态,并且不同状态下有不同的行为时,状态模式可以帮助将这些不同的行为分离到不同的状态类中,从而保持代码的清晰度和可维护性。
  3. 避免条件语句的过多嵌套
    状态模式可以减少代码中的条件语句嵌套,使代码更加易读,更易于扩展和维护。
  4. 状态转换的规则复杂且多变
    如果对象的状态转换规则非常复杂,可能会随着需求的变化而频繁修改,那么状态模式可以将状态转换逻辑集中到具体的状态类中,减少对主要对象的影响。
  5. 对象的状态可以在运行时动态改变
    状态模式允许对象在运行时切换状态,而且可以相对容易地添加新的状态类。
  6. 避免在主要对象中堆积大量的条件逻辑
    使用状态模式可以将每个状态的逻辑封装在独立的状态类中,避免在主要对象中堆积大量的状态相关的条件逻辑。

状态模式的主要角色

状态模式涉及三个主要角色:Context(上下文)、State(状态)、ConcreteState(具体状态)。状态模式的基本思想是将对象的状态封装成独立的状态类,使得对象的行为可以根据其状态的变化而改变。Context对象通过委托当前状态的行为,实现了在不同状态下的不同行为。
在使用状态模式时,Context对象通常会持有一个当前状态的引用,该引用会在运行时改变。当Context的行为需要根据状态变化而变化时,它会调用当前状态对象的方法,从而实现相应的行为。状态对象之间的切换可以在Context内部进行,或者由外部控制

  1. Context(上下文)
    Context是拥有状态的对象,它维护一个指向当前状态的引用。在状态模式中,Context的行为会随着其内部状态的改变而改变。Context类在使用状态模式时负责将请求委托给当前状态对象。它也可以提供一些方法来允许状态对象改变Context的当前状态。
  2. State(状态)
    State是一个抽象类或接口,定义了具体状态类需要实现的方法。这些方法代表了在特定状态下对象可能执行的行为。Context通过调用这些方法来委托实际的行为给当前状态对象。
  3. 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("七夕快乐!");}}

输出

当前处于编辑状态,编辑中......七夕快乐!
当前处于仅阅读状态,无法编辑
当前处于锁定状态,无法编辑

状态模式的优缺点

状态模式作为一种设计模式,具有一些优点和缺点,下面是它们的总结:
优点:

  1. 清晰的状态管理:状态模式将不同状态的行为封装在独立的状态类中,使得状态之间的转换变得清晰,减少了代码的混乱和重复。
  2. 可维护性和扩展性:由于每个状态都是一个独立的类,当需要添加新的状态时,只需要新增一个状态类,而不需要修改现有的代码。这有助于提高系统的可维护性和可扩展性。
  3. 消除大量的条件语句:状态模式可以消除大量的条件语句,从而使代码更加简洁和易于理解。状态切换的逻辑被封装在状态类内部,避免了在主要对象中堆积复杂的条件判断。
  4. 符合开闭原则:添加新的状态类不会影响到已有的代码,符合开闭原则,即对扩展开放,对修改关闭。

缺点:

  1. 增加了类的数量:引入状态模式会增加系统中的类的数量,尤其在状态较多时,可能会导致类的数量过多,增加代码量。
  2. 可能引起混乱:当状态较多时,可能会增加代码的复杂性,需要仔细管理状态之间的转换逻辑,以避免出现混乱。
  3. 不适用于简单情况:对于仅有几种状态且状态转换逻辑简单的情况,引入状态模式可能会过于复杂,不切实际。
  4. 态之间的耦合:虽然状态模式将状态之间的行为分离,但状态之间的切换仍然存在一定的耦合,需要通过Context类来进行状态的切换,可能会影响一定的灵活性。

相关文章:

设计模式二十一:状态模式(State Pattern)

一个对象的内部状态发生变化时,允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类,主要目的是将状态的行为从主要对象中分离出来,使得主要对象不必包含所有状态的逻辑,而是将每个状态的行为封装在独立的类…...

【校招VIP】产品思维能力之产品设计

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

微信小程序卡片横向滚动竖图

滚动并不是使用swiper&#xff0c;该方式使用的是scroll-view实现 Swiper局限性太多了&#xff0c;对竖图并不合适 从左往右滚动图片示例 wxml代码&#xff1a; <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.配置类&#xff0c;依赖注入…...

【AIGC】一款离线版的AI智能换脸工具V2.0分享(支持图片、视频、直播)

随着人工智能技术的爆发&#xff0c;AI不再局限于大语言模型&#xff0c;在图片处理方面也有非常大的进步&#xff0c;其中AI换脸也是大家一直比较感兴趣的&#xff0c;但这个技术的应用一直有很大的争议。 今天给大家分享一个开源你的AI换脸工具2.0&#xff0c;只需要一张所需…...

管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容选言——或

文章目录 第五章 选言命题:相容选言-或;不相容选言-要么要么第一节 选言-相容选言-或-推结论-A或B为真,则非A→B,非B→A(否一则肯一)真题(2010-28)-选言-相容选言-或-推结论-(1)A或B为真,A为假:得B为真(否一则肯一);真题(2012-29)-选言-相容选言-或-推结论-(1)…...

Git如何操作本地分支仓库?

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

WPS右键新建没有docx pptx xlsx 修复

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

【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“

文章目录 前言&#x1f31f;一、函数重载&#x1f30f;1.1.函数重载概念&#x1f30f;1.2.C支持函数重载的原理 -- 名字修饰 &#x1f31f;二、引用&#x1f30f;2.1.引用的概念&#x1f30f;2.2.引用特性&#x1f30f;2.3.常引用&#x1f30f;2.4.使用场景&#x1f30f;2.5.传…...

【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)

【关键字】 音频编码、管道模式、createEncoder 【写在前面】 在使用API6开发HarmonyOS应用时&#xff0c;如何将pcm源文件进行编码并写入文件&#xff0c;最后生成aac文件&#xff0c;本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】 import ohos.media.codec.…...

KaiwuDB CTO 魏可伟:回归用户本位,打造“小而全”的数据库

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

行业追踪,2023-08-22

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

浏览器安装selenium驱动,以Microsoft Edge安装驱动为例

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

边缘计算网关是如何提高物联网的效率的?

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

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汇市:杰克逊霍尔年会降至,鲍威尔或再发鹰派言论

环球汇市行情摘要—— 昨日&#xff0c;美元指数下跌0.11%&#xff0c;收盘在103.33点&#xff0c; 欧元升值0.22%&#xff0c;收盘价1.0898点&#xff1b; 日元贬值0.58%&#xff0c;收盘价146.23点&#xff1b; 英镑升值0.18%&#xff0c;收盘价1.2757点&#xff1b; 瑞…...

Zipkin开源的分布式链路追踪系统

Zipkin是一款开源的分布式链路追踪系统,主要功能包括: 1. 采集跟踪数据 - Zipkin client库负责收集并上报各服务的请求信息。 2. 存储跟踪数据 - 存储层默认采用Zipkin自带的基于内存的快速存储,也支持整合MySQL、Cassandra等外部存储。 3. 查询接口 - 提供RESTful API进行跟…...

java 项目运行时,后端控制台出现空指针异常---java.lang.NullPointerException

项目场景&#xff1a; 提示&#xff1a;这里简述项目背景&#xff1a; 场景如下&#xff1a; java 项目运行时&#xff0c;后端控制台出现如下图所示报错信息&#xff1a;— 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; java 项目运行时&#xff0c;后…...

模型数据处理-数据放入 session和@ModelAttribute 实现 prepare 方法详细讲解

&#x1f600;前言 本文详细讲解了模型数据处理-数据放入 session和ModelAttribute 实现 prepare 方法详细讲解 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c…...

关于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. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

华为云AI开发平台ModelArts

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

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

优选算法第十二讲:队列 + 宽搜 优先级队列

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

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...