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

设计模式使用场景实现示例及优缺点(行为型模式——状态模式)

在一个遥远的国度中,有一个被称为“变幻之城”的神奇城堡。这座城堡有一种特殊的魔法,能够随着王国的需求改变自己的形态和功能。这种神奇的变化是由一个古老的机制控制的,那就是传说中的“状态宝石”。

在变幻之城中,有四颗宝石,分别代表着不同的状态:和平、战争、丰收和灾难。每当国王决定需要改变城堡的功能时,他就会召集他的四位顾问,每位顾问负责一颗状态宝石。国王会与顾问们讨论当前的国家状况,然后选择一个最适合的状态。

比如,在和平时期,和平宝石会被激活,城堡变成一个庞大的图书馆和学术研究中心,鼓励人们学习和交流知识。而在战争来临时,战争宝石便会发光,城堡则转变为坚不可摧的堡垒,城墙厚重,箭塔林立,保护国民免受侵害。

每次状态的转换都是庄严而神圣的仪式,全城的人都会聚集在城堡广场,见证宝石的力量和城堡的变化。随着时间的推移,这座城堡不仅成为了国家的象征,也成为了人们心中希望和变革的源泉。

然而,真正的挑战来自于灾难宝石的管理。灾难宝石只在最危急的时刻被启用,城堡会转变为避难所和救援中心,为国民提供庇护和援助。但是,灾难宝石的力量非常强大,如果使用不当,可能会带来不可预测的后果。

有一次,当国王生病,无法决策时,一位野心勃勃的顾问擅自启动了灾难宝石,试图借此控制整个王国。城堡开始失控地变形,国民陷入恐慌。幸好,国王及时康复,与其他三位忠诚的顾问一起制止了这场灾难,恢复了城堡的秩序。

状态模式(State Pattern)

状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式通过将状态相关的行为封装在状态对象中,使得当对象的内部状态改变时,其行为也会随之改变,类似于它改变了其类。

核心组件

  • Context(上下文):维护一个指向当前状态对象的引用,并将与状态相关的工作委托给它。
  • State(状态):定义一个接口以封装与上下文的一个特定状态相关的行为。
  • ConcreteState(具体状态):实现状态接口的类,每个类对应一种状态和该状态下的行为。

适用场景

  1. 对象的行为依赖于它的状态
    • 对象行为随内部状态改变而改变时,可以使用状态模式而不是在对象操作中使用大量的条件分支。
  2. 业务逻辑包含大量与对象状态有关的条件语句
    • 当一个操作中包含巨大的多分支条件转移语句,且这些分支依赖于对象状态时,状态模式可以将分支处理移动到它们各自的状态类中。

实现实例

以音乐播放器的播放、暂停、停止等状态转换为例,通过状态模式管理状态改变带来的行为改变。

状态接口(State Interface)

定义了状态相关行为的方法。

public interface State {void doAction(Context context); // 执行与状态相关的行为,并更新上下文的状态
}

具体状态(Concrete State)

实现不同状态下的具体行为。

PlayingState
public class PlayingState implements State {public void doAction(Context context) {System.out.println("Music is playing"); // 执行播放音乐的行为context.setState(this); // 更新上下文的状态}public String toString(){return "Playing State"; // 返回状态信息}
}
PausedState
public class PausedState implements State {public void doAction(Context context) {System.out.println("Music is paused"); // 执行暂停音乐的行为context.setState(this); // 更新上下文的状态}public String toString(){return "Paused State"; // 返回状态信息}
}
StoppedState
public class StoppedState implements State {public void doAction(Context context) {System.out.println("Music is stopped"); // 执行停止音乐的行为context.setState(this); // 更新上下文的状态}public String toString(){return "Stopped State"; // 返回状态信息}
}

上下文(Context)

管理和委托给当前状态对象的类。

public class MusicPlayerContext {private State state; // 当前状态对象public MusicPlayerContext(){state = null; // 初始化状态为空}public void setState(State state){this.state = state; // 设置当前状态}public State getState(){return state; // 获取当前状态}
}

客户端代码(Client Code)

演示状态模式的使用。

public class Client {public static void main(String[] args) {MusicPlayerContext context = new MusicPlayerContext(); // 创建上下文对象State playing = new PlayingState(); // 创建播放状态对象playing.doAction(context); // 执行播放音乐的行为并更新状态System.out.println(context.getState().toString()); // 输出当前状态信息State paused = new PausedState(); // 创建暂停状态对象paused.doAction(context); // 执行暂停音乐的行为并更新状态System.out.println(context.getState().toString()); // 输出当前状态信息State stopped = new StoppedState(); // 创建停止状态对象stopped.doAction(context); // 执行停止音乐的行为并更新状态System.out.println(context.getState().toString()); // 输出当前状态信息}
}

解释

  • 状态接口(State Interface):定义了 doAction(Context context) 方法,所有具体状态类都必须实现这个方法。
  • 具体状态(Concrete State):实现 State 接口,定义了在特定状态下的具体行为。PlayingStatePausedStateStoppedState 分别定义了播放、暂停和停止音乐的行为。
  • 上下文(Context)MusicPlayerContext 类保存了当前状态对象,并提供了设置和获取当前状态的方法。
  • 客户端代码(Client Code):客户端代码创建具体的状态和上下文对象,并通过执行行为和更新状态来模拟音乐播放器的状态转换。

这种设计模式的优势在于将与状态相关的行为局部化,并且将特定状态的行为分配到代表该状态的类中。这样做可以避免代码中的大量条件语句,并使得系统更易于理解和维护。

优缺点

优点
  1. 封装状态转换规则
    • 状态模式将所有与某个状态相关的行为都封装在一个类中,也可以在类内部维护状态转换的逻辑。
  2. 增加新的状态简单
    • 添加新状态只需增加一个新的具体状态类,无需修改现有的代码,符合开闭原则。
缺点
  1. 增加对象数量
    • 每个状态都需要一个具体的类,随着状态数量增加,系统中类的个数也会增多。

类图

+----------------+         +---------------+         +-----------------+
|    Context     |<------->|     State     |<--------|  ConcreteState  |
+----------------+         +---------------+         +-----------------+
| - state        |         | + doAction()  |         | + doAction()    |
+----------------+         +---------------+         +-----------------+

总结

状态模式通过将每个状态的行为封装在对应的状态类中,使得状态转换逻辑分布于这些状态类,而非其他对象。这种模式适合于状态多变且相互依赖的系统,可以清晰地组织和管理状态转换的逻辑。

相关文章:

设计模式使用场景实现示例及优缺点(行为型模式——状态模式)

在一个遥远的国度中&#xff0c;有一个被称为“变幻之城”的神奇城堡。这座城堡有一种特殊的魔法&#xff0c;能够随着王国的需求改变自己的形态和功能。这种神奇的变化是由一个古老的机制控制的&#xff0c;那就是传说中的“状态宝石”。 在变幻之城中&#xff0c;有四颗宝石&…...

抖音短视频seo矩阵系统源码(搭建技术开发分享)

#抖音矩阵系统源码开发 #短视频矩阵系统源码开发 #短视频seo源码开发 一、 抖音短视频seo矩阵系统源码开发&#xff0c;需要掌握以下技术&#xff1a; 网络编程&#xff1a;能够使用Python、Java或其他编程语言进行网络编程&#xff0c;比如使用爬虫技术从抖音平台获取数据。…...

基于 asp.net家庭财务管理系统设计与实现

博主介绍&#xff1a;专注于Java .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用感兴趣的可以先…...

allure_pytest:AttributeError: ‘str‘ object has no attribute ‘iter_parents‘

踩坑记录 问题描述&#xff1a; 接口自动化测试时出现报错&#xff0c;报错文件是allure_pytest库 问题分析&#xff1a; 自动化测试框架是比较成熟的代码&#xff0c;报错也不是自己写的文件&#xff0c;而是第三方库&#xff0c;首先推测是allure_pytest和某些库有版本不兼…...

C语言 反转链表

题目链接:https://leetcode.cn/problems/reverse-linked-list/description/?envTypestudy-plan-v2&envIdselected-coding-interview 完整代码: /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/// 反转链表…...

MFC CRectTracker 类用法详解

CRectTracker 类并非 Microsoft Foundation Class (MFC) 库中应用很广泛的一个类&#xff0c;一般教科书中很少有提到。在编程中如果需编写选择框绘制以及选择框大小调整、移动等程序时&#xff0c;用CRectTracker 类就会做到事半而功倍。下面详细介绍MFC CRectTracker 类。 M…...

好玩的调度技术-场景编辑器

好玩的调度技术-场景编辑器 文章目录 好玩的调度技术-场景编辑器前言一、演示一、代码总结好玩系列 前言 这两天写前端写上瘾了&#xff0c;顺手做了个好玩的东西&#xff0c;好玩系列也好久没更新&#xff0c;正好作为素材写一篇文章&#xff0c;我真的觉得蛮好玩的&#xff…...

提高自动化测试脚本编写效率 5大关键注意事项

提高自动化测试脚本编写效率能加速测试周期&#xff0c;减少人工错误&#xff0c;提升软件质量&#xff0c;促进项目按时交付&#xff0c;增强团队生产力和项目成功率。而自动化测试脚本编写效率低下&#xff0c;往往会导致测试周期延长&#xff0c;增加项目成本&#xff0c;延…...

护眼落地灯哪个更护眼?2024年度最值得入手的5款护眼大路灯推荐

落地灯和台灯哪个更护眼&#xff1f;之所以我们眼睛经常酸痛&#xff0c;很大部分的原因是因为我们长时间在不良光线下&#xff0c;将注意力集中在屏幕或书本上会导致眼睛肌肉过度使用&#xff0c;引发疲劳和酸痛。但也不排除不正确的坐姿或者工作环境缺乏适当的照明引起的&…...

DP讨论——适配器、桥接、代理、装饰器模式通用理解

学而时习之&#xff0c;温故而知新。 共性 适配器、桥接、代理和装饰器模式&#xff0c;实现上基本没啥区别&#xff0c;怎么区分&#xff1f;只能从上下文理解&#xff0c;看目的是啥。 它们&#xff0c;我左看上看下看右看&#xff0c;发现理解可以这么简单:都是A类调用B/…...

Apache AGE的MATCH子句

MATCH子句允许您在数据库中指定查询将搜索的模式。这是检索数据以在查询中使用的主要方法。 通常在MATCH子句之后会跟随一个WHERE子句&#xff0c;以添加用户定义的限制条件到匹配的模式中&#xff0c;以操纵返回的数据集。谓词是模式描述的一部分&#xff0c;不应被视为仅在匹…...

Netty Websocket

一、WebSocket 协议概述 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许服务端主动向客户端推送数据&#xff0c;从而实现了实时通信。WebSocket 建立在 HTTP 之上&#xff0c;但与 HTTP 的轮询&#xff08;Polling&#xff09;和长轮询&#xff08;Long Pol…...

用户注册业务逻辑、接口设计和实现、前端逻辑

一、用户注册业务逻辑分析 二、用户注册接口设计和定义 2.1. 设计接口基本思路 对于接口的设计&#xff0c;我们要根据具体的业务逻辑&#xff0c;设计出适合业务逻辑的接口。设计接口的思路&#xff1a; 分析要实现的业务逻辑&#xff1a; 明确在这个业务中涉及到几个相关子…...

ubuntu搭建harbor私仓

1、环境准备 链接: https://pan.baidu.com/s/1q4XBWPd8WdyEn4l253mpUw 提取码: 7ekx --来自百度网盘超级会员v2的分享 准备一台Ubuntu 机器:192.168.124.165 将上面两个文件考入Ubuntu上面 2、安装harbor 安装Docker Harbor仓库以容器方式运行,需要先安装好docker,参考:…...

深层神经网络示例

维度说明&#xff1a; A[L]、Z[L]&#xff1a;&#xff08;本层神经元个数、样本数&#xff09; W[L]&#xff1a;&#xff08;本层神经元个数、上层神经元个数&#xff09; b[L]&#xff1a;&#xff08;本层神经元个数、1&#xff09; dZ[L]&#xff1a;dA[L] * g’A&#xf…...

vue中获取剪切板中的内容

目录 1.说明 2.示例 3.总结 1.说明 在系统中的画面或者时外部文件中进行拷贝处理后&#xff0c;在页面中可以获取剪切板的内容。 2.示例 方式①(直接获取) // 异步函数获取剪切板内容 async function getClipboardContent(ev: any) {try {ev.preventDefault()const clip…...

十五、【机器学习】【监督学习】- 神经网络回归

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…...

知识图谱和 LLM:利用Neo4j驾驭大型语言模型(探索真实用例)

这是关于 Neo4j 的 NaLLM 项目的一篇博客文章。这个项目是为了探索、开发和展示这些 LLM 与 Neo4j 结合的实际用途。 2023 年,ChatGPT 等大型语言模型 (LLM) 因其理解和生成类似人类的文本的能力而风靡全球。它们能够适应不同的对话环境、回答各种主题的问题,甚至模拟创意写…...

目标检测入门:4.目标检测中的一阶段模型和两阶段模型

在前面几章里&#xff0c;都只做了目标检测中的目标定位任务&#xff0c;并未做目标分类任务。目标检测作为计算机视觉领域的核心人物之一&#xff0c;旨在从图像中识别出所有感兴趣的目标&#xff0c;并确定它们的类别和位置。现在目标检测以一阶段模型和两阶段模型为代表的。…...

zookeeper+kafka消息队列群集部署

kafka拓扑架构 zookeeper拓扑架构...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

WebRTC调研

WebRTC是什么&#xff0c;为什么&#xff0c;如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...