设计模式之 状态模式

状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时,改变其行为。这种模式将状态的转换和行为的变化解耦,将不同状态的行为封装到独立的状态类中,而通过上下文(Context)来管理当前状态。每个状态类都负责处理与自己相关的行为,并且能够根据当前的状态转移到下一个状态。

状态模式的主要优点是可以避免在单一类中出现复杂的条件判断语句,增强系统的可扩展性和维护性。

一、状态模式的定义

状态模式允许一个对象在其内部状态改变时,改变其行为。也就是说,状态模式的核心思想是,状态的改变不仅仅是数据的变化,还会影响到行为的变化。每个状态类都有自己的行为实现,而当对象的状态发生变化时,它会切换到一个新的状态对象,这个新的状态对象将根据当前的状态执行相应的行为。

二、状态模式的组成部分

状态模式主要由以下几个部分构成:

  1. Context(上下文)

    上下文类负责维护当前状态并向外界提供一个接口。它还负责在状态变化时更新当前状态对象。上下文通过一个指向状态接口的引用来调用当前状态的行为。
  2. State(状态接口)

    定义一个状态接口,表示对象在不同状态下的行为。每个具体状态类都实现这个接口,并根据当前状态执行具体的操作。
  3. ConcreteState(具体状态类)

    具体的状态类,它实现了状态接口,封装了与该状态相关的行为。每个状态类的实现将描述在该状态下的具体行为和可能的状态转换。

三、状态模式的工作原理

状态模式的工作原理是将对象的所有可能状态封装在状态类中。当对象的状态发生变化时,通过上下文切换到新的状态类,并由新的状态类处理相应的行为。每个状态类内有自己处理请求的逻辑,状态类之间是独立的,并且状态的变化是由上下文自动控制的。

这种模式使得客户端不需要知道具体的状态类,只需要知道当前状态是什么,调用上下文的 request() 方法即可。

四、状态模式的代码示例

假设我们有一个简单的订单处理系统,其中订单的状态有多个,如 待支付已支付已发货 等,每个状态下的订单处理行为不同。

  • 定义状态接口
    public interface State {public void handleOrder(Context context);
    }
  • 创建具体状态类
    public class PendingPaymentState implements State{@Overridepublic void handleOrder(Context context) {System.out.println("订单已支付");context.setState(new PaidState());}
    }
    public class PaidState implements State{@Overridepublic void handleOrder(Context context) {System.out.println("订单已发货");context.setState(new ShippedState());}
    }
    
    public class CompletedState implements State{@Overridepublic void handleOrder(Context context) {System.out.println("订单已完成");}
    }
  • 定义上下文类
    public class Context {private State state;public Context(State state) {this.state = state;}public void setState(State state) {this.state = state;}public void handle(){state.handleOrder(this);}
    }
  • 客户端代码
    public class Client {public static void main(String[] args) {Context context = new Context(new PendingPaymentState());context.handle();context.handle();context.handle();}
    }
  • 运行结果

五、状态模式的优缺点

优点:
  1. 消除复杂的条件判断:状态模式将状态行为与状态的转换分离,避免了在单一类中使用大量 ifswitch 语句。每个状态类只处理其对应状态下的行为,状态之间的切换逻辑也被隔离到不同的类中。

  2. 灵活性和扩展性:当需要增加新的状态时,只需要添加一个新的状态类,而不需要修改现有的代码。这符合开放封闭原则(对扩展开放,对修改关闭)。

  3. 代码更加清晰和易于维护:状态模式将不同的状态行为抽象为独立的类,这使得代码更加模块化,易于理解和维护。

  4. 容易实现状态切换:每个状态类都有自己的行为,当上下文需要切换状态时,只需更新上下文的状态属性即可。状态切换过程封装在状态类中,避免了外部操作的干扰。

缺点:
  1. 类的数量增加:每个状态都会对应一个具体的类,因此如果状态很多,会导致类的数量增加,可能使得系统结构变得复杂。

  2. 状态间切换的耦合性:虽然状态类的行为是独立的,但状态切换本身是通过上下文进行的,可能会导致上下文与状态之间的耦合性较强。

  3. 状态间的过度共享:在某些情况下,不同的状态之间可能有相似的行为或状态转换逻辑,可能导致一些冗余的代码。虽然可以通过抽象层次来减少重复,但也可能增加理解和维护的难度。

六、状态模式的应用场景

  1. 有多个状态的对象:状态模式非常适用于对象有多个不同的状态,并且不同状态下的行为各不相同的场景。比如在一个自动售货机的状态变化过程中,机器根据支付情况、货物是否有库存等条件改变行为。

  2. 工作流管理:在复杂的工作流系统中,每个任务的状态往往决定了任务的处理方式。使用状态模式可以使得每个任务的状态和行为更加清晰独立。

  3. 游戏开发:在游戏中,角色或场景的状态(例如“待机”、“行走”、“攻击”)常常影响到角色的行为。使用状态模式能够简化这些状态的管理。

  4. 事务管理系统:例如订单的不同阶段(如待支付、已支付、已发货等)可能会有不同的处理方法,状态模式能够很好的将不同阶段的处理逻辑分离开来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/476663.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习日志015--python单链表

创建 class Node:def __init__(self,data):# 数据域self.data data# 链接域self.next Noneclass LinkList:def __init__(self,):# 初始化头节点self.head None# 记录链表的长度self.size 0 增加 #头插def insert_head(self,value):# 创建新节点node Node(value)q self…

CSP/信奥赛C++语法基础刷题训练(22):洛谷P1075:[NOIP2012 普及组] 质因数分解

CSP/信奥赛C语法基础刷题训练(22):洛谷P1075:[NOIP2012 普及组] 质因数分解 题目描述 已知正整数 n n n 是两个不同的质数的乘积,试求出两者中较大的那个质数。 输入格式 输入一个正整数 n n n。 输出格式 输出…

Java开发经验——开发常用工具类

摘要 本文介绍了Java开发中常用的工具类,包括Apache Commons Collections的SetUtils、Google Guava的Sets、Apache Commons Lang的ArrayUtils等,以及它们在集合操作、数组操作、字符串处理、JSON处理等方面的应用。文章还涉及了Optional类、Money工具类…

【Python TensorFlow】进阶指南(续篇三)

在前几篇文章中,我们探讨了TensorFlow的高级功能,包括模型优化、分布式训练、模型解释等多个方面。本文将进一步深入探讨一些更具体和实用的主题,如模型持续优化的具体方法、异步训练的实际应用、在线学习的实现细节、模型服务化的最佳实践、…

阿里系 acw_sc__v3 某教学网站

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 有相关问题请第一时间头像私信联系我删…

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点: STP的选举(Listening状态中): RSTP P/A(提议/同意)机制 同步机制: 边缘端口的配置: RSTP的端口角色划分: ensp模拟…

ChatGPT 与其他 AI 技术在短视频营销中的技术应用与协同策略

摘要: 本文深入探讨了 ChatGPT 及其他 AI 技术在短视频营销中的应用。从技术层面剖析了这些技术如何助力短视频内容创作、个性化推荐、用户互动以及营销效果评估等多方面,通过具体方法分析、数据引用与大模型工具介绍,旨在为短视频营销领域提…

数据结构-树状数组专题(2)

一、前言 接上回树状数组专题&#xff08;1&#xff09;&#xff0c;这次主要介绍差分跟树状数组联动实现区间更新 二、我的模板 重新放了一遍&#xff0c;还是提一嘴&#xff0c;注意下标从0开始&#xff0c;区间左闭右开 template <typename T> struct Fenwick {in…

使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程

当涉及到图数据时&#xff0c;复杂性是不可避免的。无论是社交网络中的庞大互联关系、像 Freebase 这样的知识图谱&#xff0c;还是推荐引擎中海量的数据量&#xff0c;处理如此规模的图数据都充满挑战。 尤其是当目标是生成能够准确捕捉这些关系本质的嵌入表示时&#xff0c;…

启动前后端分离项目笔记

一、项目 首先可以在各大开源软件拿取一个项目&#xff0c;以下项目是在gitee上获取 二、准备工作 配置JDK环境&#xff0c;node.js环境&#xff0c;安装vue脚手架工具以及maven环境 三、前端项目启动 在前端目录下安装依赖 npm install 如果报错可能是因为权限不够&#…

3个月,2000+台虚机迁移成功!

在全球数字化浪潮的推动下&#xff0c;各国政务部门纷纷加速信息化与数字化转型&#xff0c;以提升服务效率和数据安全。在这一背景下&#xff0c;墨西哥某政府部门因迅速增长的政务数字化需求&#xff0c;选择与华为云合作&#xff0c;构建专属的政务私有云平台。 经过多方尝…

GRU (门控循环单元 - 基于RNN - 简化LSTM又快又好 - 体现注意力的思想) + 代码实现 —— 笔记3.5《动手学深度学习》

目录 0. 前言 1. 门控隐状态 1.1 重置门和更新门 1.2 候选隐状态 1.3 隐状态 2. 从零开始实现 2.1 初始化模型参数 2.2 定义模型 2.3 训练与预测 3 简洁实现 4. 小结 0. 前言 课程全部代码&#xff08;pytorch版&#xff09;已上传到附件看懂上一篇RNN的所有细节&am…

微知-plantuml常用语法和要点以及模板?(note over、create、box,endbox、alt,else,end, autonumber)

文章目录 常见语法常用 线条类实线虚线斜箭头或奇数箭头 A ->(10) B: B->(10) A分割线&#xff1a;newpage 颜色类给箭头指定颜色 -[#red]->给某个note加颜色&#xff1a; note over Alice, Bob #FFAAAA: xxx给分组信息着色 alt#red 分组类alt xxx; else xxx; else xx…

YOLOV5/rknn生成可执行文件部署在RK3568上

接上一篇文章best-sim.rknn模型生成好后&#xff0c;我们要将其转换成可执行文件运行在RK3568上&#xff0c;这一步需要在rknpu上进行&#xff0c;在强调一遍&#xff01;&#xff01;rknpu的作用是可以直接生成在开发板上运行的程序 退出上一步的docker环境 exit1.复制best-…

2024信创数据库TOP30之蚂蚁集团OceanBase

数据库作为存储、管理和分析这些数据的关键工具&#xff0c;其地位自然不言而喻。随着信息技术的日新月异&#xff0c;数据库技术也在不断演进&#xff0c;以满足日益复杂多变的市场需求。近日&#xff0c;备受瞩目的“2024信创数据库TOP30”榜单由DBC联合CIW/CIS权威发布&…

Kafka 生产者优化与数据处理经验

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…

【强化学习的数学原理】第02课-贝尔曼公式-笔记

学习资料&#xff1a;bilibili 西湖大学赵世钰老师的【强化学习的数学原理】课程。链接&#xff1a;强化学习的数学原理 西湖大学 赵世钰 文章目录 一、为什么return重要&#xff1f;如何计算return&#xff1f;二、state value的定义三、Bellman公式的详细推导四、公式向量形式…

006-自定义枚举注解

自定义枚举注解 一、业务需求描述1.问题描述2.解决方案 二、创建一个描述注解三、创建一个枚举注解四、创建一个枚举五、创建一个配置文件六、场景实战1.在 RequestParam 前面使用2.在非 Model 的实体类上使用3.在 RequestBody 对应的实体类中使用 七、效果展示 一、业务需求描…

数据库表设计范式

华子目录 MYSQL库表设计&#xff1a;范式第一范式&#xff08;1NF&#xff09;第二范式&#xff08;2NF&#xff09;第三范式&#xff08;3NF&#xff09;三范式小结巴斯-科德范式&#xff08;BCNF&#xff09;第四范式&#xff08;4NF&#xff09;第五范式&#xff08;5NF&…

力扣刷题--21.合并两个有序链表

I am the best &#xff01;&#xff01;&#xff01; 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2…