状态设计模式是什么?什么是 State 状态设计模式?Python 状态设计模式示例代码
什么是 State 状态设计模式?
状态设计模式是一种行为型设计模式,它允许一个对象在其内部状态发生改变时改变其行为,使其看起来好像改变了其类。状态模式主要解决的问题是:当一个对象的行为取决于它的状态,并且在运行时可能需要根据状态改变其行为。

主要思想:
状态模式允许对象在内部状态改变时改变它的行为。它将对象的状态封装成独立的类,使得对象在不同的状态下有不同的行为,而且能够在运行时切换状态,但不改变其代码结构。
主要角色:
- Context(环境): 定义客户感兴趣的接口,并且维护一个具体状态子类的实例,以定义当前的状态。
- State(状态): 定义一个接口,用于封装 Context 对象的特定状态相关的行为。
- ConcreteState(具体状态): 每个具体状态子类都实现了 State 接口,并且定义了该状态下的行为。

工作流程:
- 定义一个 Context 类,其中包含一个 State 类型的对象引用,表示当前的状态。
- 定义一个 State 接口,包含了可能在不同状态下的操作方法。
- 对于每个具体状态,创建一个具体的状态类,实现 State 接口,并在 Context 类中维护这些状态对象。
优点:
-
清晰的状态管理: 状态设计模式使得状态和状态之间的转换变得清晰可见。每个状态都被封装成独立的类,便于管理和维护。
-
遵循开放-封闭原则: 可以在不改变原有代码的情况下,动态地添加新的状态,遵循了开放-封闭原则,使系统更易于扩展。
-
消除条件语句: 使用状态模式可以避免大量的条件语句,将对象的行为与其状态解耦,使得代码更简洁、清晰。
-
简化代码结构: 状态模式可以使得每个状态都是一个独立的类,简化了对象的代码结构,降低了代码的复杂度。
缺点:
-
类的数量增加: 对于有限状态机,可能会产生大量的状态类,增加了类的数量,使得系统变得复杂。
-
状态转换逻辑复杂: 如果状态之间的转换逻辑非常复杂,可能会导致状态模式的实现也变得复杂,需要谨慎设计。
-
不适用于所有情况: 状态模式并不适用于所有场景,特别是当状态之间的转换逻辑比较简单时,可能会显得过于繁琐。
-
可能影响性能: 对象在不同状态下的行为可能会受到状态切换的影响,有时可能会增加额外的开销,影响性能。
总的来说,状态设计模式在管理对象状态和行为上提供了一种清晰的方式,但需要在适当的场景中使用,同时考虑到状态之间的复杂性、数量和性能等方面。
Python 实现状态设计模式示例代码(一):
# Context 环境类
class Context:def __init__(self, state):self._state = statedef request(self):self._state.handle()def change_state(self, state):self._state = state# State 状态接口
class State:def handle(self):pass# ConcreteState 具体状态类
class ConcreteStateA(State):def handle(self):print("Handling in State A")class ConcreteStateB(State):def handle(self):print("Handling in State B")# 使用示例
context = Context(ConcreteStateA())
context.request() # 输出:Handling in State A
context.change_state(ConcreteStateB())
context.request() # 输出:Handling in State B
在这个示例中,Context 是环境类,维护一个状态对象的引用。State 是状态接口,ConcreteStateA 和 ConcreteStateB 是具体状态类,分别表示不同的状态。通过状态模式,可以使得对象在不同状态下表现出不同的行为。
Python 实现状态设计模式示例代码(二):
当你想要管理用户的登录状态时,状态设计模式可以提供一个良好的示例。在这个示例中,用户可能处于已登录或未登录状态,并且根据不同的状态,系统将展现不同的行为。
# Context 环境类 - User
class User:def __init__(self):self._state = Nonedef set_state(self, state):self._state = statedef get_state(self):return self._statedef perform_action(self):self._state.perform_action()# State 状态接口
class State:def perform_action(self):pass# ConcreteState 具体状态类
class LoggedInState(State):def perform_action(self):print("Performing actions for a logged-in user.")class LoggedOutState(State):def perform_action(self):print("Performing actions for a logged-out user.")# 使用示例
user = User()
user.set_state(LoggedInState())
user.perform_action() # 输出:Performing actions for a logged-in user.user.set_state(LoggedOutState())
user.perform_action() # 输出:Performing actions for a logged-out user.
在这个示例中,User 是环境类,维护一个状态对象的引用,State 是状态接口,LoggedInState 和 LoggedOutState 是具体状态类。根据用户的状态,可以执行不同的操作。当用户登录或退出登录时,状态会相应地改变,系统将展现不同的行为。
使用状态设计模式时,需要注意哪些地方?
-
状态切换的逻辑: 确保状态之间的转换逻辑清晰和合理。状态切换可能会受到某些条件或事件的影响,确保状态转换的逻辑正确性。
-
状态的数量: 状态设计模式适用于有限数量的状态。如果状态过多,可能会导致类的数量急剧增加,使得系统变得复杂。
-
状态的一致性: 确保状态对象在不同状态下表现出一致的接口和行为,保持状态之间的一致性。
-
Context 对象的状态管理: Context 对象需要维护当前状态,并在状态变化时更新其状态。确保 Context 对象正确地管理和切换状态。
-
状态间的通信: 状态之间可能需要进行通信,例如在状态切换时传递数据或信息。确保状态之间的通信方式合理可靠。
-
单一职责原则: 确保每个具体状态类只关注特定状态下的行为,遵循单一职责原则,保持代码的清晰度和可维护性。
-
测试和验证: 对状态设计模式进行充分的测试和验证,确保状态切换和对象行为符合预期。
-
选择合适的模式: 状态设计模式并不适用于所有情况。在确定使用状态模式之前,要考虑是否有更适合的模式来解决问题。
综上所述,使用状态设计模式时需要注意状态之间的切换逻辑、状态的一致性、Context 对象的状态管理等方面,以确保模式的正确性和系统的可维护性。
本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇
相关文章:
状态设计模式是什么?什么是 State 状态设计模式?Python 状态设计模式示例代码
什么是 State 状态设计模式? 状态设计模式是一种行为型设计模式,它允许一个对象在其内部状态发生改变时改变其行为,使其看起来好像改变了其类。状态模式主要解决的问题是:当一个对象的行为取决于它的状态,并且在运行时…...
电力感知边缘计算技术网关产品设计方案-硬件方案
网关硬件架构设计图: 1.配置方案 配置差异 A类网关 B类网关 CPU...
【线性代数与矩阵论】坐标变换与相似矩阵
坐标变换与相似矩阵 2023年11月4日 #algebra 文章目录 坐标变换与相似矩阵1. 基变换与坐标变换2. 相似变换下链 1. 基变换与坐标变换 坐标变换与基变换都要通过过渡矩阵 A A A 来实现。设有一向量 f ⃗ \vec f f , x x x 是在基 α \alpha α 下该向量的坐标…...
C语言编译过程再解析
多年以前,分析过编译过程,并写了一篇博客,现在对编译过程有了更广阔的认识,记录在此 编译过程 中的 链接与 编译 编译过程分为1. 预处理2. 编译3. 汇编4. 链接其中有 2个过程比较特殊,1. 编译2. 链接对于C程序来说,链接分为提前链接(静态链接)对应下图第1行运行时链接(动态链…...
GeoTrust证书
GeoTrust证书的特点与优势: 1,广泛的浏览器兼容性: GeoTrust证书得到了各大主流浏览器的广泛支持,确保您的网站能够在用户使用的任何浏览器上获得正常的安全连接。 2,强大的加密技术: GeoTrust采用先进的…...
肾合胶囊 | 冬不养肾春易病,若出现了这六大表现,小心是肾虚!
冬季作为一年中最寒冷的季节,自然万物皆静谧闭藏,而肾具有潜藏、封藏、闭藏精气的特点,是封藏之本,肾的脏腑特性与冬季相通应,所以在冬季更应该重视养肾。 而现在正值初冬,正是开始养肾的最佳时间。此时培…...
IDEA中常用快捷键
整理了一些IDEA开发常用的快捷键: 快捷键组合实现效果psvm Tab键 / main Tab键public static void main(String[] args)sout Tab键System.out.println()Ctrl X删除当前行Ctrl D复制当前行AltInsert(或右键Generate)生成代码(如get,set方法,构造函数等)CtrlAltT…...
注解之@Configuration、@Bean、@Component
目录 前言 Component:通用的注解! Bean 引入第三方的类 Configuration 前言 首先:我们先简单描述一下这三个的作用 Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。 Bean注解告诉Spring这个方法将会…...
【Web安全】sql注入绕过技法
sql注入绕过技法 1. 注释符号绕过 原理:SQL注释符号(如--, /* */)可以用来忽略查询的一部分,特别是在注入点之后的部分。这对于绕过需要闭合的查询或移除查询余下部分的情况特别有用。 -- 注释内容 # 注释内容 /*注释内容*/ ;2…...
Axios使用方式
ajax是JQUERY封装的XMLHttprequest用来发送http请求 Axios简单点说它就是一个js库,支持ajax请求,发送axios请求功能更加丰富,丰富在哪不知道 1.npm使用方式 vue项目中 npm install axios 2.cdn方式 <script src"https://unpkg.com/axios/dist/axios.min.js">…...
kotlin 内置函数对数组进行各种操作
以下是一些常见的用法示例: plus() 函数将两个数组合并成一个数组。plus() 函数是 Kotlin 标准库中的一个扩展函数,可以用于合并两个同类型的数组。 fun main() {val array1 arrayOf(1, 2, 3)val array2 arrayOf(4, 5, 6)val mergedArray array1.plu…...
力扣labuladong——一刷day54
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣1660. 纠正二叉树二、力扣100. 相同的树三、力扣572. 另一棵树的子树四、力扣101. 对称二叉树 前言 判断树是否相等,就直接遍历就可以。判断…...
3、MSF使用
文章目录 一、利用ms17-010漏洞对靶机执行溢出攻击二、后渗透模块meterpreter的使用 一、利用ms17-010漏洞对靶机执行溢出攻击 分别输入以下命令,使用ms17_010_eternalblue模块对目标机的ms17-010漏洞进行利用: use exploit/windows/smb/ms17_010_eter…...
34970A 数据采集 / 数据记录仪开关单元
34970A 数据采集 / 数据记录仪开关单元 产品综述: Keysight 34970A 数据采集/数据记录仪开关单元由一个 3 插槽主机和一个内置的 6 1/2 位数字万用表组成。每个通道可以单独配置,以测量 11 种不同功能之一,这样既不会增加成本,也…...
BUUCTF刷题之路-web-[GXYCTF2019]Ping Ping Ping1
启动环境后,是一个简简单单的页面: 看样子是能够触发远程执行漏洞的。尝试下ping 127.0.0.1,如果有回显说明我们的想法是对的。 最近才学习的nc反弹shell。想着是否能用nc反弹shell的办法。控制服务器然后输出flag呢?于是我测试下…...
一、深入简出串口(USRT)通信——基本概念。
一、前言 串口到底是什么?简单来说一句话就可以解释,串口就是一种通信协议。 看到这里可能大家会觉得你这不是放屁么,说了跟没说一样。所以这里做前言来描述,大家要先对通信协议有一个下意识地认识才能在学习串口的时候不至于迷茫…...
采用connector-c++ 8.0操作数据库
1.下载最新的Connector https://dev.mysql.com/downloads/connector/cpp/,下载带debug的库。 解压缩到本地,本次使用的是带debug模式的connector库: 注:其中mysqlcppconn与mysqlcppconn8的区别是: 2.在cmakelist…...
【Java数据结构 -- 时间和空间复杂度】
时间和空间复杂度 1. 算法效率2. 时间复杂度2.1 时间复杂度的概念2.2 大O的渐进表示法2.3 推导大O阶方法2.4 常见时间复杂度计算举例例1例2例3例4 计算 bubbleSort的时间复杂度例5 计算binarySearch的时间复杂度?例6 计算阶乘递归factorial的时间复杂度?…...
【每日一题】1457. 二叉树中的伪回文路径-2023.11.25
题目: 1457. 二叉树中的伪回文路径 给你一棵二叉树,每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的,当它满足:路径经过的所有节点值的排列中,存在一个回文序列。 请你返回从根到叶子节点的所有路…...
能让PDF看起来像是扫描件的Look Scanned
什么是 Look Scanned ? Look Scanned 是一个能够让 PDF 看起来就像是扫描件一样的纯前端网站。你再也不需要麻烦地打印之后扫描了,你所需要的就是鼠标点几下。 这是个挺有意思的软件,但是老苏不确定什么场景下会用到这个软件,如果不想自己搭…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
