Java设计模式:行为型模式→状态模式

Java 状态模式详解

1. 定义

状态模式(State Pattern)是一种行为型设计模式,它允许对象在内部状态改变时改变其行为。状态模式通过将状态需要的行为封装在不同的状态类中,实现对象行为的动态改变。该模式的核心思想是分离不同状态的行为,并利用状态对象替代传统的条件判断语句。

2. 基本思想

状态模式的基本思想是将对象的状态封装成独立的状态类,并通过状态对象来控制行为的切换。当对象的状态变化时,它会切换到新的状态,相应的行为也会随之改变。通过这种方式,状态模式使得状态管理更加清晰,减少了复杂的条件判断,提高了代码的可维护性。

3. 基本原理

状态模式主要包括以下几个组成部分:

  • 上下文(Context):维护当前状态,并定义客户端与具体状态之间的交互。上下文包含一个对状态对象的引用。
  • 状态接口(State):定义了状态的行为接口,所有具体状态类需要实现该接口。
  • 具体状态类(Concrete State):实现状态接口,并实现与具体状态相关的行为。
    在这里插入图片描述

更多实用资源:

http://sj.ysok.net/jydoraemon 访问码:JYAM

4. 实现方式

4.1 基本实现

4.1.1 状态接口

定义一个状态接口,描述状态应实现的方法:

public interface State {void doAction(Context context);
}
4.1.2 上下文类

定义上下文类,维护对状态的引用:

public class Context {private State state;public void setState(State state) {this.state = state;}public State getState() {return state;}public void request() {state.doAction(this);}
}
4.1.3 具体状态类

实现具体状态类,定义具体的行为:

public class ConcreteStateA implements State {@Overridepublic void doAction(Context context) {System.out.println("State A Action.");context.setState(this); // 设置当前状态为 State A}
}public class ConcreteStateB implements State {@Overridepublic void doAction(Context context) {System.out.println("State B Action.");context.setState(this); // 设置当前状态为 State B}
}
4.1.4 客户端代码

客户端代码使用状态模式:

public class Client {public static void main(String[] args) {Context context = new Context();ConcreteStateA stateA = new ConcreteStateA();stateA.doAction(context); // 执行状态 A 的操作System.out.println(context.getState().getClass().getSimpleName());ConcreteStateB stateB = new ConcreteStateB();stateB.doAction(context); // 执行状态 B 的操作System.out.println(context.getState().getClass().getSimpleName());}
}

4.2 代码分析

  • 状态接口(State):定义了状态的行为,每个具体状态都需要实现该接口。
  • 上下文类(Context):维护当前状态,并委托请求给当前状态的对象。
  • 具体状态类(ConcreteStateA, ConcreteStateB):实现具体的状态逻辑,根据状态改变定义相应的行为。
  • 客户端:通过上下文对象与状态对象进行交互,切换状态并执行对应的行为。

5. 工作流程

  1. 定义状态接口:创建一个接口以定义不同状态的行为。
  2. 实现具体状态类:实现状态接口的类,为每种状态定义对应的处理逻辑。
  3. 创建上下文类:管理状态的切换和状态间的交互,维护当前状态的引用。
  4. 客户端使用:通过上下文对象来调用行为和切换状态。

6. 变种

  1. 多状态模式:使用状态模式来管理复杂的多状态交互。
  2. 状态机模式:结合状态模式和状态机理论,增强对状态转移的控制。

7. 实际应用

状态模式在实际开发中的应用非常广泛,以下是一些典型的应用场景:

  1. 图形用户界面:在 GUI 开发中,组件的不同状态(如按钮的激活、禁用、悬停等)可以通过状态模式来实现。
  2. 游戏开发:角色的不同状态(如行走、跳跃、攻击等),通过状态模式进行状态的管理与转换。
  3. 工作流系统:处理业务过程中的不同状态(如待审批、已审批、拒绝),通过状态模式实现不同的操作。

8. 使用场景

使用状态模式的场景包括:

  • 当对象的行为依赖于其状态,并且需要在运行时根据状态改变行为时。
  • 当需要避免使用大量的条件语句来判断和执行状态转换时。
  • 当状态和行为之间的关系非常紧密,能够出现多种状态的变化时。

9. 优缺点

优点

  1. 简化代码:通过分离状态的行为减少复杂性,避免大量的条件语句。
  2. 灵活性高:便于添加新状态和状态的变化,更易于扩展。
  3. 遵循开闭原则:可以在不修改现有代码的前提下增加新的状态。

缺点

  1. 状态类可能会过多:对于状态非常多的情况,会导致类的数量增加,管理上可能会变得复杂。
  2. 上下文依赖性问题:上下文与具体状态有耦合关系,可能在状态传递上造成影响。

10. 最佳实践

  1. 明确状态与行为:状态和行为之间的关系清晰,状态切换逻辑透明,便于维护。
  2. 管理状态的变化:合理规划状态的切换,确保状态变化不会影响系统的整体逻辑。
  3. 代码重用与扩展:在实现状态模式时,注意在能重用的基础上实现扩展,避免重复代码。

11. 注意事项

  1. 避免过度设计:在状态树不复杂的情况下,使用状态模式可能会导致设计过于复杂。
  2. 合理命名状态类:使用有意义的命名使状态类的职责和作用更加明显。
  3. 关注状态转移的条件:确保状态转移逻辑明确,避免引入混淆。

12. 常见的误区

  • 认为状态模式只适合简单状态:状态模式同样适用复杂系统和业务状态转换。
  • 状态变化会导致内存泄漏:需要注意对状态对象的有效管理,防止因状态切换导致的对象引用问题。
  • 状态模式是单纯使用状态类:状态模式关注的不仅是状态本身,而是规范状态之间的互动及其影响。

13. 常见问题

  • 状态模式的核心组成部分是什么?

    • 包括状态接口、具体状态类、上下文类和客户端。
  • 如何判断使用状态模式的适用性?

    • 当对象的行为依赖于其状态,并且状态转换频繁或复杂时,适合使用状态模式。
  • 状态模式与策略模式的关系是什么?

    • 状态模式主要用于对状态的切换,而策略模式则主要用于对行为的选择。两者在实现方式上有所差异,但可以结合使用。

14. 总结

状态模式是一种行为型设计模式,通过将状态的行为封装在独立的状态类中,使得对象的行为能够在状态变化时进行改变。这种模式不仅提高了系统的灵活性和可维护性,还降低了对象间的耦合度,简化了代码逻辑。在实际开发中,根据具体情况合理使用状态模式,将有助于更好地管理复杂业务逻辑、提升代码的可读性和可扩展性。通过对状态模式的深入理解,开发者可以创建更强大且高效的 Java 应用程序,理清对象之间的关系,并有效针对不同的状态和行为做出合适的反应。

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

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

相关文章

蓝桥与力扣刷题(234 回文链表)

题目:给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2: 输入&…

【面经】字节南京一面部分题目记录

南京字节一面题,可能因为项目不太匹配,全程八股比较多,也有两道手撕代码题,强度还是有的。为了方便大家学习,大部分答案由GPT整理,有些题给出了我认为回答比较好的博客链接。 文章目录 一、python2 和 pyth…

【C语言篇】“三子棋”

一、游戏介绍 三子棋,英文名为 Tic - Tac - Toe,是一款简单而经典的棋类游戏。游戏在一个 33 的棋盘上进行,两名玩家轮流在棋盘的空位上放置自己的棋子(通常用 * 和 # 表示),率先在横、竖或斜方向上连成三个…

vscode软件操作界面UI布局@各个功能区域划分及其名称称呼

文章目录 abstract检查用户界面的主要区域官方文档关于UI的介绍 abstract 检查 Visual Studio Code 用户界面 - Training | Microsoft Learn 本质上,Visual Studio Code 是一个代码编辑器,其用户界面和布局与许多其他代码编辑器相似。 界面左侧是用于访…

【B站保姆级视频教程:Jetson配置YOLOv11环境(六)PyTorchTorchvision安装】

Jetson配置YOLOv11环境(6)PyTorch&Torchvision安装 文章目录 1. 安装PyTorch1.1安装依赖项1.2 下载torch wheel 安装包1.3 安装 2. 安装torchvisiion2.1 安装依赖2.2 编译安装torchvision2.2.1 Torchvisiion版本选择2.2.2 下载torchvisiion到Downloa…

于动态规划的启幕之章,借 C++ 笔触绘就算法新篇

注意:代码由易到难 P1216 [IOI 1994] 数字三角形 Number Triangles 题目链接:[IOI 1994] 数字三角形 Number Triangles - 洛谷 题目描述 观察下面的数字金字塔。 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每…

分页按钮功能

前言 在前端开发中,分页功能是一个常见的需求,特别是当需要展示大量数据时,它能有效提升用户体验。该文章结合运用了HTML,CSS,JS实现网页的分页按钮功能,并且可以选择每页显示的条数试试更新总页数及显示当…

SAP HCM 回溯分析

最近总有人问回溯问题,今天把12年总结的笔记在这共享下: 12年开这个图的时候总是不明白是什么原理,教程看N次,网上资料找一大堆,就是不明白原理,后来为搞明白逻辑,按照教材的数据一样做&#xf…

gitea - fatal: Authentication failed

文章目录 gitea - fatal: Authentication failed概述run_gitea_on_my_pkm.bat 笔记删除windows凭证管理器中对应的url认证凭证启动gitea服务端的命令行正常用 TortoiseGit 提交代码备注END gitea - fatal: Authentication failed 概述 本地的git归档服务端使用gitea. 原来的用…

X Window System 架构概述

X Window System 架构概述 1. X Server 与 X Client ​ 这里引入一张维基百科的图,在Linux系统中,若用户需要图形化界面,则可以使用X Window System,其使用**Client-Server**架构,并通过网络传输相关信息。 ​ ​ X…

Linux防火墙基础

一、Linux防火墙的状态机制 1.iptables是可以配置有状态的防火墙,其有状态的特点是能够指定并记住发送或者接收信息包所建立的连接状态,其一共有四种状态,分别为established invalid new related。 established:该信息包已建立连接&#x…

[论文学习]Adaptively Perturbed Mirror Descent for Learning in Games

[论文学习]Adaptively Perturbed Mirror Descent for Learning in Games 前言概述前置知识和问题约定单调博弈(monotone game)Nash均衡和Gap函数文章问题定义Mirror Descent 方法评价 前言 文章链接 我们称集合是紧的,则集合满足&#xff1…

Go学习:类型转换需注意的点 以及 类型别名

目录 1. 类型转换 2. 类型别名 1. 类型转换 在从前的学习中,知道布尔bool类型变量只有两种值true或false,C/C、Python、JAVA等编程语言中,如果将布尔类型bool变量转换为整型int变量,通常采用 “0为假,非0为真”的方…

使用Pygame制作“吃豆人”游戏

本篇博客展示如何使用 Python Pygame 编写一个简易版的“吃豆人(Pac-Man)” 风格游戏。这里我们暂且命名为 Py-Man。玩家需要控制主角在一个网格地图里移动、吃掉散布在各处的豆子,并躲避在地图中巡逻的幽灵。此示例可帮助你理解网格地图、角…

ubuntu磁盘扩容

ubuntu磁盘扩容 描述先在虚拟机设置里面扩容进入Ubuntu 配置使用命令行工具parted进行分区输出如下完成 描述 执行命令,查看 fs 类型是什么 lsblk -o NAME,FSTYPE,MOUNTPOINT将60G扩容到100G,其中有些操作我也不知道什么意思,反正就是成功了&#xff0…

redis底层数据结构

底层数据结构 了解下这些咱常用的数据其底层实现是啥 在提到使用哪类数据结构之前,先来了解下redis底层到底有多少种数据结构 1,sds动态字符串 概念与由来 redis是一种使用C语言编写的nosql,redis存储的key数据均为string结构&#xff0…

ChatGPT怎么回事?

纯属发现,调侃一下~ 这段时间deepseek不是特别火吗,尤其是它的推理功能,突发奇想,想用deepseek回答一些问题,回答一个问题之后就回复服务器繁忙(估计还在被攻击吧~_~) 然后就转向了GPT&#xf…

趣味Python100例初学者练习01

1. 1 抓交通肇事犯 一辆卡车违反交通规则,撞人后逃跑。现场有三人目击该事件,但都没有记住车号,只记下了车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前…

2024-我的学习成长之路

因为热爱,无畏山海

蓝桥杯备考:高精度算法之除法

我们除法的高精度其实也不完全是高精度,而是一个高精度作被除数除以一个低精度 模拟我们的小学除法 由于题目中我们的除数最大是1e9,当它真正是1e9的时候,t是有可能超过1e9的,所以要用long long