当前位置: 首页 > 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...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

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

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

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...