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

状态模式(State Pattern)详解

1. 引言

在很多软件系统中,对象的行为往往依赖于其内部状态,而状态的变化又会影响对象的行为。状态模式(State Pattern)为解决这一问题提供了一种优雅的方法。通过将状态的行为封装到独立的状态对象中,可以使得对象在其内部状态改变时能够改变其行为。

2. 状态模式的定义

状态模式是一种行为型设计模式,它允许一个对象在其内部状态改变时改变其行为。状态模式将与对象的状态相关的行为设计成单独的状态类,使得状态之间的转换变得更加简单和灵活。这种模式使得代码的可读性和维护性提高,同时也降低了复杂度。

3. 适用场景

  • 当一个对象的行为依赖于其状态,并且需要在运行时改变状态时。
  • 当状态转移较多时,避免使用大量的条件语句(如 if-else 或 switch-case)。
  • 当需要将状态相关的行为和数据封装在一起时,提供对外部代码的解耦。

4. 结构

状态模式主要包括以下角色:

  • 上下文(Context): 持有一个状态对象,维护当前的状态,允许状态之间的切换。
  • 状态接口(State): 定义了所有具体状态的公共接口,通常包括用于处理请求的方法。
  • 具体状态(Concrete State): 实现了状态接口,封装了与特定状态相关的行为。

5. 示例代码

以下是一个使用状态模式的简单示例,模拟一个简单的电灯状态:开和关。

5.1 状态接口

// 状态接口
interface State {void handle(Context context);
}

CopyInsert

5.2 具体状态

// 具体状态:开
class OnState implements State {@Overridepublic void handle(Context context) {System.out.println("电灯已经打开。");context.setState(new OffState()); // 切换到关状态}
}// 具体状态:关
class OffState implements State {@Overridepublic void handle(Context context) {System.out.println("电灯已经关闭。");context.setState(new OnState()); // 切换到开状态}
}

CopyInsert

5.3 上下文

// 上下文类
class Context {private State currentState;public Context() {currentState = new OffState(); // 默认状态为关}public void setState(State state) {currentState = state;}public void request() {currentState.handle(this);}
}

CopyInsert

5.4 客户端代码

public class StatePatternDemo {public static void main(String[] args) {Context context = new Context();// 请求变化状态context.request(); // 输出:电灯已经关闭。context.request(); // 输出:电灯已经打开。context.request(); // 输出:电灯已经关闭。}
}

CopyInsert

6. 优缺点

6.1 优点

  • 清晰的结构: 状态行为与上下文分离,使得各个状态的行为清晰且易于维护。
  • 减少条件语句: 避免大量的条件判断,提高代码的可读性。
  • 灵活性: 可以在运行时动态切换状态,增强了系统的灵活性和可扩展性。

6.2 缺点

  • 状态类数量可能增加: 每个状态都需创建一个类,可能导致类的数量快速增长,增加安全维护难度。
  • 对象的切换可能导致混乱: 状态切换不当可能产生不符合预期的状态,特别是在复杂状态转移时,难以追踪和调试。

7. 总结

状态模式是一种非常实用的设计模式,尤其适合处理对象在各种内部状态下表现出不同的行为。通过将状态和行为封装在独立的类中,状态模式不仅提高了代码的可维护性,也使得对象的行为更加灵活。在实际开发中,合理应用状态模式能够显著提高系统的灵活度和可扩展性,特别是在涉及复杂状态和行为变化的场景中。

相关文章:

状态模式(State Pattern)详解

1. 引言 在很多软件系统中,对象的行为往往依赖于其内部状态,而状态的变化又会影响对象的行为。状态模式(State Pattern)为解决这一问题提供了一种优雅的方法。通过将状态的行为封装到独立的状态对象中,可以使得对象在…...

ajax微信静默登录不起效不跳转问题

问题描述: 今天通过ajax调用方式做微信静默登录,发现本地可以跳转,到线上地址死活都不跳转,就像没起作用一般,经许久排查发现,是因为https和http域名的问题,线上只配置了http域名&#xff0…...

参数估计理论

估计理论的主要任务是在某种信号假设下,估算该信号中某个参数(比如幅度、相位、达到时间)的具体取值。 参数估计:先假定研究的问题具有某种数学模型, 如正态分布,二项分布,再用已知类别的学习样…...

mybatis插入数据运行成功但数据库没有数据,id却在增长,是什么原因??

错误描述: mybatis插入数据运行成功,但是数据库却没有数据,id也在增加 原因:在测试方法上面加了 Transactional 虽然日志显示插入语句执行成功,但可能事务在提交过程中出现了问题。比如在后续的操作中有异常抛出导…...

Hadoop简介及单点伪分布式安装

目录 1. 大数据2. Hadoop简介3. Hadoop伪分布式安装4. Hadoop启动参考 1. 大数据 大数据的定义:一种规模大到在获取、存储、管理、分析方面大大超出传统数据库软件工具能力范围的数据集合。   特征:   1.海量的数据规模   2.快速的数据流转   3.…...

网站架构知识之Ansible模块(day021)

1.Ansible模块 作用:通过ansible模块实现批量管理 2.command模块与shell模块 command模块是ansible默认的模块,适用于执行简单的命令,不支持特殊符号 案列01,批量获取主机名 ansible all -m command -a hostname all表示对主机清单所有组…...

是时候用开源降低AI落地门槛了

过去三十多年,从Linux到KVM,从OpenStack到Kubernetes,IT领域众多关键技术都来自开源。开源技术不仅大幅降低了IT成本,也降低了企业技术创新的门槛。 那么,在生成式AI时代,开源能够为AI带来什么?…...

操作系统学习笔记-5.1-IO设备

文章目录 I/O控制器I/O 控制器的组成I/O 控制器的工作流程I/O 控制器的类型I/O 控制器的主要功能I/O 控制器与操作系统的交互DMA 的工作原理DMA 传输模式DMA 控制器的组成 组成内存映像I/O,寄存器独立编址 IO软件层次用户层 I/O 软件设备独立性软件层设备驱动程序中…...

页面、组件、应用、生命周期(微信小程序)

文章目录 页面生命周期函数组件生命周期函数应用(App)生命周期函数页面与组件生命周期的执行顺序注意事项 在微信小程序中,生命周期函数是指页面或组件在不同阶段会被自动调用的特定函数。这些函数可以帮助开发者在适当的时机完成特定的初始化…...

书生第四期实训营进阶岛——L2G4000 InternVL 多模态模型部署微调实践

基础任务 体验InternVL 运行demo 效果如下: 使用XTuner对InternVL进行微调 运行demo 效果如下:...

国内 ChatGPT中文版镜像网站整理合集(2024/11/08)

一、GPT中文镜像站 ① yixiaai.com 支持GPT4、4o以及o1,支持MJ绘画 ② chat.lify.vip 支持通用全模型,支持文件读取、插件、绘画、AIPPT ③ AI Chat 支持GPT3.5/4,4o以及MJ绘画 1. 什么是镜像站 镜像站(Mirror Site&#xff…...

SpringBoot整合Liquibase对数据库管理和迁移

简介 Liquibase是一个用于用于跟踪、管理和应用数据库变化的开源工具,通过日志文件(changelog)的形式记录数据库的变更(changeset),然后执行日志文件中的修改,将数据库更新或回滚(rollback)到一致的状态。它的目标是提供一种数据库类型无关的…...

太空旅游:科技能否让星辰大海变为现实?

内容概要 在这个快速变化的时代,太空旅游成为了一个让人热血沸腾的话题。想象一下,坐在一颗漂浮的太空舱里,手中端着饮料,眺望着无尽的星辰大海,简直就像科幻电影中的情节一样。不过,这不仅仅是一个空洞的…...

[JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决

目录 一. 多线程下使用ArrayList 1.1. 自行判断加锁 1.2 使用Collections.synchronizedList()套壳加锁 1.3 CopyOnWriteArrayList类 二. 总结 一. 多线程下使用ArrayList 多线程下使用ArrayList会涉及到线程安全问题, 例如: public static void main(String[] args) thro…...

Elasticsearch-linux环境部署

本文主要介绍linux下elasticsearch的部署。通过在一台linux服务器中分别对elasticsearch-6.7.2版本,elasticsearch-7.3.0版本来进行安装,记录在安装elasticsearch-7.3.0版本时出现的异常情况,以及elasticsearch-head的安装。 基础环境 本机已…...

LeetCode 每日一题 长度为 K 的子数组的能量值

长度为 K 的子数组的能量值 给你一个长度为 n 的整数数组 nums 和一个正整数 k 。 一个数组的 能量值 定义为: 如果 所有 元素都是依次 连续 且 上升 的,那么能量值为 最大 的元素。 否则为 -1 。 你需要求出 nums 中所有长度为 k 的 子数组 的能量值。 …...

人工智能——小白学习指南

知孤云出岫 目录 1. **智能评测系统**2. **个性化学习路径推荐**3. **虚拟学习助手**4. **学习行为分析**5. **数据驱动的教学决策**6. **自动化课程推荐**7. **数据隐私与安全保护** 人工智能知识点的总结和学习路线,以数据表格形式呈现,并附带在教育行…...

go 集成Gin Web开发框架

引入gin的依赖 下载并安装 gin go get -u github.com/gin-gonic/gin 将 gin 引入到代码中 import "github.com/gin-gonic/gin" 开始 package mainimport "github.com/gin-gonic/gin"func main() {r : gin.Default()r.GET("/ping", func(c …...

c++ 多态性

类的多态 多态概念入门 #include <iostream> using namespace std;/* 多态的前提: 拥有继承关系的类中有相同的函数(返回类型、函数名、形参列表) 多态解决的问题&#xff1a;1、派生类的对象被赋值给基类对象时2、派生类的对象初始化基类的引用时3、基类的指针指向派生…...

块存储、文件存储和对象存储详细介绍

块存储、文件存储和对象存储介绍 块存储&#xff1a;像跑车&#xff0c;因为它们都能提供快速的响应和高性能&#xff0c;适合需要即时数据访问的场景&#xff0c;比如数据库和虚拟化技术。 文件存储&#xff1a;像货车&#xff0c;因为它们都能承载大量货物&#xff08;文件&…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

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

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

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...