设计模式使用场景实现示例及优缺点(行为型模式——状态模式)
在一个遥远的国度中,有一个被称为“变幻之城”的神奇城堡。这座城堡有一种特殊的魔法,能够随着王国的需求改变自己的形态和功能。这种神奇的变化是由一个古老的机制控制的,那就是传说中的“状态宝石”。
在变幻之城中,有四颗宝石,分别代表着不同的状态:和平、战争、丰收和灾难。每当国王决定需要改变城堡的功能时,他就会召集他的四位顾问,每位顾问负责一颗状态宝石。国王会与顾问们讨论当前的国家状况,然后选择一个最适合的状态。
比如,在和平时期,和平宝石会被激活,城堡变成一个庞大的图书馆和学术研究中心,鼓励人们学习和交流知识。而在战争来临时,战争宝石便会发光,城堡则转变为坚不可摧的堡垒,城墙厚重,箭塔林立,保护国民免受侵害。
每次状态的转换都是庄严而神圣的仪式,全城的人都会聚集在城堡广场,见证宝石的力量和城堡的变化。随着时间的推移,这座城堡不仅成为了国家的象征,也成为了人们心中希望和变革的源泉。
然而,真正的挑战来自于灾难宝石的管理。灾难宝石只在最危急的时刻被启用,城堡会转变为避难所和救援中心,为国民提供庇护和援助。但是,灾难宝石的力量非常强大,如果使用不当,可能会带来不可预测的后果。
有一次,当国王生病,无法决策时,一位野心勃勃的顾问擅自启动了灾难宝石,试图借此控制整个王国。城堡开始失控地变形,国民陷入恐慌。幸好,国王及时康复,与其他三位忠诚的顾问一起制止了这场灾难,恢复了城堡的秩序。
状态模式(State Pattern)
状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式通过将状态相关的行为封装在状态对象中,使得当对象的内部状态改变时,其行为也会随之改变,类似于它改变了其类。
核心组件
- Context(上下文):维护一个指向当前状态对象的引用,并将与状态相关的工作委托给它。
- State(状态):定义一个接口以封装与上下文的一个特定状态相关的行为。
- ConcreteState(具体状态):实现状态接口的类,每个类对应一种状态和该状态下的行为。
适用场景
- 对象的行为依赖于它的状态:
- 对象行为随内部状态改变而改变时,可以使用状态模式而不是在对象操作中使用大量的条件分支。
- 业务逻辑包含大量与对象状态有关的条件语句:
- 当一个操作中包含巨大的多分支条件转移语句,且这些分支依赖于对象状态时,状态模式可以将分支处理移动到它们各自的状态类中。
实现实例
以音乐播放器的播放、暂停、停止等状态转换为例,通过状态模式管理状态改变带来的行为改变。
状态接口(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接口,定义了在特定状态下的具体行为。PlayingState、PausedState和StoppedState分别定义了播放、暂停和停止音乐的行为。 - 上下文(Context):
MusicPlayerContext类保存了当前状态对象,并提供了设置和获取当前状态的方法。 - 客户端代码(Client Code):客户端代码创建具体的状态和上下文对象,并通过执行行为和更新状态来模拟音乐播放器的状态转换。
这种设计模式的优势在于将与状态相关的行为局部化,并且将特定状态的行为分配到代表该状态的类中。这样做可以避免代码中的大量条件语句,并使得系统更易于理解和维护。
优缺点
优点
- 封装状态转换规则:
- 状态模式将所有与某个状态相关的行为都封装在一个类中,也可以在类内部维护状态转换的逻辑。
- 增加新的状态简单:
- 添加新状态只需增加一个新的具体状态类,无需修改现有的代码,符合开闭原则。
缺点
- 增加对象数量:
- 每个状态都需要一个具体的类,随着状态数量增加,系统中类的个数也会增多。
类图
+----------------+ +---------------+ +-----------------+
| Context |<------->| State |<--------| ConcreteState |
+----------------+ +---------------+ +-----------------+
| - state | | + doAction() | | + doAction() |
+----------------+ +---------------+ +-----------------+
总结
状态模式通过将每个状态的行为封装在对应的状态类中,使得状态转换逻辑分布于这些状态类,而非其他对象。这种模式适合于状态多变且相互依赖的系统,可以清晰地组织和管理状态转换的逻辑。
相关文章:
设计模式使用场景实现示例及优缺点(行为型模式——状态模式)
在一个遥远的国度中,有一个被称为“变幻之城”的神奇城堡。这座城堡有一种特殊的魔法,能够随着王国的需求改变自己的形态和功能。这种神奇的变化是由一个古老的机制控制的,那就是传说中的“状态宝石”。 在变幻之城中,有四颗宝石&…...
抖音短视频seo矩阵系统源码(搭建技术开发分享)
#抖音矩阵系统源码开发 #短视频矩阵系统源码开发 #短视频seo源码开发 一、 抖音短视频seo矩阵系统源码开发,需要掌握以下技术: 网络编程:能够使用Python、Java或其他编程语言进行网络编程,比如使用爬虫技术从抖音平台获取数据。…...
基于 asp.net家庭财务管理系统设计与实现
博主介绍:专注于Java .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用感兴趣的可以先…...
allure_pytest:AttributeError: ‘str‘ object has no attribute ‘iter_parents‘
踩坑记录 问题描述: 接口自动化测试时出现报错,报错文件是allure_pytest库 问题分析: 自动化测试框架是比较成熟的代码,报错也不是自己写的文件,而是第三方库,首先推测是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) 库中应用很广泛的一个类,一般教科书中很少有提到。在编程中如果需编写选择框绘制以及选择框大小调整、移动等程序时,用CRectTracker 类就会做到事半而功倍。下面详细介绍MFC CRectTracker 类。 M…...
好玩的调度技术-场景编辑器
好玩的调度技术-场景编辑器 文章目录 好玩的调度技术-场景编辑器前言一、演示一、代码总结好玩系列 前言 这两天写前端写上瘾了,顺手做了个好玩的东西,好玩系列也好久没更新,正好作为素材写一篇文章,我真的觉得蛮好玩的ÿ…...
提高自动化测试脚本编写效率 5大关键注意事项
提高自动化测试脚本编写效率能加速测试周期,减少人工错误,提升软件质量,促进项目按时交付,增强团队生产力和项目成功率。而自动化测试脚本编写效率低下,往往会导致测试周期延长,增加项目成本,延…...
护眼落地灯哪个更护眼?2024年度最值得入手的5款护眼大路灯推荐
落地灯和台灯哪个更护眼?之所以我们眼睛经常酸痛,很大部分的原因是因为我们长时间在不良光线下,将注意力集中在屏幕或书本上会导致眼睛肌肉过度使用,引发疲劳和酸痛。但也不排除不正确的坐姿或者工作环境缺乏适当的照明引起的&…...
DP讨论——适配器、桥接、代理、装饰器模式通用理解
学而时习之,温故而知新。 共性 适配器、桥接、代理和装饰器模式,实现上基本没啥区别,怎么区分?只能从上下文理解,看目的是啥。 它们,我左看上看下看右看,发现理解可以这么简单:都是A类调用B/…...
Apache AGE的MATCH子句
MATCH子句允许您在数据库中指定查询将搜索的模式。这是检索数据以在查询中使用的主要方法。 通常在MATCH子句之后会跟随一个WHERE子句,以添加用户定义的限制条件到匹配的模式中,以操纵返回的数据集。谓词是模式描述的一部分,不应被视为仅在匹…...
Netty Websocket
一、WebSocket 协议概述 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。它允许服务端主动向客户端推送数据,从而实现了实时通信。WebSocket 建立在 HTTP 之上,但与 HTTP 的轮询(Polling)和长轮询(Long Pol…...
用户注册业务逻辑、接口设计和实现、前端逻辑
一、用户注册业务逻辑分析 二、用户注册接口设计和定义 2.1. 设计接口基本思路 对于接口的设计,我们要根据具体的业务逻辑,设计出适合业务逻辑的接口。设计接口的思路: 分析要实现的业务逻辑: 明确在这个业务中涉及到几个相关子…...
ubuntu搭建harbor私仓
1、环境准备 链接: https://pan.baidu.com/s/1q4XBWPd8WdyEn4l253mpUw 提取码: 7ekx --来自百度网盘超级会员v2的分享 准备一台Ubuntu 机器:192.168.124.165 将上面两个文件考入Ubuntu上面 2、安装harbor 安装Docker Harbor仓库以容器方式运行,需要先安装好docker,参考:…...
深层神经网络示例
维度说明: A[L]、Z[L]:(本层神经元个数、样本数) W[L]:(本层神经元个数、上层神经元个数) b[L]:(本层神经元个数、1) dZ[L]:dA[L] * g’A…...
vue中获取剪切板中的内容
目录 1.说明 2.示例 3.总结 1.说明 在系统中的画面或者时外部文件中进行拷贝处理后,在页面中可以获取剪切板的内容。 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.目标检测中的一阶段模型和两阶段模型
在前面几章里,都只做了目标检测中的目标定位任务,并未做目标分类任务。目标检测作为计算机视觉领域的核心人物之一,旨在从图像中识别出所有感兴趣的目标,并确定它们的类别和位置。现在目标检测以一阶段模型和两阶段模型为代表的。…...
zookeeper+kafka消息队列群集部署
kafka拓扑架构 zookeeper拓扑架构...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...
