【Python设计模式14】状态模式

状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态改变时改变其行为。状态模式将不同状态的行为封装到不同的状态类中,使得状态之间的转换独立于对象本身,减少了条件语句的使用,提高了代码的可维护性和可扩展性。

状态模式的结构

状态模式主要包括以下几个角色:

  1. 上下文(Context):维护一个具体状态的实例,这个实例定义了当前对象的状态。
  2. 状态(State):定义一个接口,用于封装与上下文的一个特定状态相关的行为。
  3. 具体状态(ConcreteState):实现状态接口,具体实现与上下文的一个特定状态相关的行为。

状态模式的示例

假设我们有一个电灯的开关类,电灯有两种状态:开和关。我们可以使用状态模式来实现这一需求。

定义状态接口
from abc import ABC, abstractmethodclass State(ABC):@abstractmethoddef handle(self, context):pass
定义具体状态类
class OnState(State):def handle(self, context):print("Turning light off...")context.state = OffState()class OffState(State):def handle(self, context):print("Turning light on...")context.state = OnState()
定义上下文类
class LightSwitch:def __init__(self):self.state = OffState()  # 初始状态为关def press(self):self.state.handle(self)
使用状态模式
def main():switch = LightSwitch()# 切换状态switch.press()  # 输出:Turning light on...switch.press()  # 输出:Turning light off...switch.press()  # 输出:Turning light on...switch.press()  # 输出:Turning light off...if __name__ == "__main__":main()

在这个示例中,State是状态接口,定义了处理状态转换的方法。OnStateOffState是具体状态类,分别实现了灯处于开和关状态时的行为。LightSwitch是上下文类,维护了一个当前状态的实例,并通过调用状态实例的handle方法来切换状态。

状态模式的优缺点

优点
  1. 简化状态转换逻辑:状态模式通过将状态转换逻辑封装到状态类中,简化了上下文类的代码,使得状态转换更加清晰。
  2. 提高可维护性和可扩展性:状态模式使得添加新状态变得容易,只需定义新的状态类并更新上下文类的状态管理逻辑即可。
  3. 符合单一职责原则:状态模式将与状态相关的行为封装到状态类中,使得上下文类和状态类各自职责单一。
缺点
  1. 增加类的数量:状态模式会增加系统中类的数量,导致代码复杂性增加。
  2. 状态转换逻辑分散:状态模式将状态转换逻辑分散到各个状态类中,可能导致代码不容易理解和维护。

状态模式的适用场景

  1. 对象行为依赖于状态变化:当一个对象的行为依赖于其状态,并且需要在运行时根据状态改变行为时,可以使用状态模式。
  2. 避免条件语句:当需要避免在代码中使用大量条件语句来管理状态转换时,可以使用状态模式。
  3. 状态数量较多:当一个对象有多个状态,并且这些状态之间的转换逻辑复杂时,可以使用状态模式。

状态模式与策略模式的区别

  1. 意图不同
    • 状态模式:用于对象在不同状态下行为的变化。
    • 策略模式:用于在运行时选择不同的算法或策略。
  2. 状态模式涉及状态转换:状态模式中的状态类通常会改变上下文的状态,从而引发状态转换。而策略模式中的策略类不会改变上下文的状态。
  3. 上下文的角色不同:状态模式中的上下文角色更加主动,它管理和切换状态。策略模式中的上下文则主要负责使用策略,而策略的选择可能由客户端决定。

总结

状态模式是一种行为型设计模式,通过将对象的不同状态的行为封装到不同的状态类中,使得对象在状态改变时可以改变其行为。状态模式适用于对象行为依赖于状态变化、需要避免条件语句和状态数量较多的场景。合理应用状态模式,可以提高代码的可维护性和可扩展性,简化状态转换逻辑。理解并掌握状态模式,有助于在实际开发中构建灵活、易维护的系统。

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

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

相关文章

Design and implementation of robot impedance controller

机器人阻抗控制器的设计与实现是一个复杂但关键的过程,它涉及到多个方面以确保机器人能够在外界环境的影响下保持稳定的性能。以下是对机器人阻抗控制器设计与实现的详细解答: 一、阻抗控制原理 阻抗控制的基本原理是建立一个期望的机器人位置和接触力…

股票交易vip快速通道有什么门槛?vip交易通道的开通流程!

证券公司的VIP通道通常是为了满足高端客户或高频交易客户的需求而设立的,提供更快速、更便捷的交易服务。证券公司VIP通道适用于有追涨停板需求的投资者,以及一些喜爱高频交易的投资者,总的来说就是快速,在交易主机排队靠前。 VI…

go-zero 实战(1)

环境准备 go 版本 go version go1.22.2 linux/amd64 goctl 安装 goctl(官方建议读 go control)是 go-zero微服务框架下的代码生成工具。使用 goctl 可以显著提升开发效率,让开发人员将时间重点放在业务开发上,其功能有&#xff1a…

pands使用openpyxl引擎实现EXCEL条件格式

通过python的openpyxl库,实现公式条件格式。 实现内容:D列单元格不等于E列同行单元格时标红。 #重点是formula后面的公式不需要“”号。 from openpyxl.styles import Color, PatternFill, Font, Border from openpyxl.styles.differential import Dif…

Java客户端SpringDataRedis(RedisTemplate)上手

文章目录 ⛄概述⛄快速入门❄️❄️导入依赖❄️❄️配置文件❄️❄️测试代码 ⛄数据化序列器⛄StringRedisTemplate⛄RedisTemplate的两种序列化实践方案总结 ⛄概述 SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模…

LLM学习笔记

Q1:SFT时,计算LOSS ​ LLM是自回归生成模型,每次只会生成一个 token,难道 SFT 时,对于一个 (L, D) 的数据,要调用 L 次LLM去计算loss? A1: ​ 在每个前向传播过程,模型…

HDU 2196 Computer(树形dp)

H D U 2196 C o m p u t e r (树形 d p ) \Huge{HDU 2196 Computer(树形dp)} HDU2196Computer(树形dp) 文章目录 题意思路标程 题目链接:Problem - 2196 (hdu.edu.cn) 题意 给出一个n个节点的无…

论AI大模型炼丹与练舞的关系

AI大模型的训练和微调的区别,就像是在舞蹈中学习基础动作和编排新的舞蹈一样。 想象一下,你有一个神奇的舞蹈机器人,只要给它足够的舞蹈视频,它就能学会各种各样的舞步。 模型训练的过程就像是给这个舞蹈教练机器人一个包含了各种…

git将某次提交合并到另一个分支

一、需求背景 将分支b中的某一次提交单独合并到分支a 二、实现方案 需求:将分支b中的某一次提交单独合并到分支a 1.在git上查看指定某次提交的id,如下图所示: 也可以通过git log命令查看提交的id,如下图: git log…

CNN网络的介绍及实战

卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习模型,它在计算机视觉领域取得了巨大成功。CNN的设计灵感来自于生物学中的视觉系统,旨在模拟人类视觉处理的方式。CNN由多层卷积层和池化层堆叠而成&…

【AIGC调研系列】MiniCPM-Llama3-V2.5模型与GPT-4V对比

MiniCPM-Llama3-V2.5模型与GPT-4V的对比可以从多个方面进行分析,包括性能、应用场景和技术特点。 从性能角度来看,MiniCPM-Llama3-V2.5在OCR识别、模型幻觉能力和空间理解能力方面表现出色,实现了开源模型的性能SOTA(State of th…

Android13 基座充电屏保

屏幕保护有两个设置可选:默认为插入基座充电时 通过DreamBackend启用屏保,并且保存选择的时机 //QSSI.13\packages\apps\Settings\src\com\android\settings\dream\WhenToDreamPicker.java Override protected boolean setDefaultKey(String key) {mBac…

LeetCode hot100-50-G

124. 二叉树中的最大路径和二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。路径和 是路径中各节点值的总和。给你一个二叉树的根…

linux input 驱动

使用文档 设备树修改 新增一个 LED 节点 arch/arm/boot/dts/arm/vexpress-v2p-ca9.dts my_pl_led {compatible = "arm, cortex-a9-led";status = "okay";};设备树编译 make dtbs日志 DTC arch/arm/boot/dts/arm/vexpress

AI视频换脸!最快的方法,100%成功,完全免费,无需配置、打开即用

这是一款百分百完全免费,超级好用又简单的AI视频换脸工具,不仅效果非常不错而且支持CPU和GPU解码,即使电脑上没有独立显卡,你也可以通过电脑上的CPU要进解码,虽然我之前给他介绍好几个有关AI视频,比如像这个…

通关!游戏设计之道Day17

音乐里的音符 音乐能给任何娱乐体验增色不少。 主题公园景区,电影或电子游戏都少不了它。 在考虑音乐设计时,你需要弄清楚的第一个问题是:“我想要什么类型的音乐?” 关于这个问题,确切的答案有两个:用…

46. 全排列 - 力扣(LeetCode)

基础知识要求: Java:方法、集合、泛型、Arrays工具类、数组、for循环、if判断 Python: 方法、列表、for循环、if判断 题目: 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案…

网络原理-HTTPS协议

在前面说到HTTP中,我们通过抓包,可以看到许多信息内容,其中往往会包含一些敏感信息,这些都是明文传输,当我们的请求被黑客或者不法分子截获后,那就很危险了,因此衍生出了HTTPS协议来对传输数据进行加密。 一、加密原理 基本原理如下: 明文 密钥 > 密文 密文…

【一竞技DOTA2】RAMZES666替补参加裂变联赛

1、根据主办方文件,RAMZES666将继续作为Tundra战队替补参加裂变联赛。该比赛为欧洲线上赛,于5月27日-30日举行,总奖金8万美元。 除此之外,Nigma战队在上个月宣布四号位Matthew离队后,也选择启用老队员GH参赛。而在本月初让ah fu转回教练、携替补Thiolicor出战PGL瓦拉几亚的Secr…

远程户外监控组网方案,工业4G路由器ZR2000

户外监控无人值守4G工业路由器组网应用涉及工业自动化、数据传输和远程监控的重要领域。在户外没有光纤的情况下,想要让监控或传感器等设备联网,仅需一台4G工业路由器即可解决。以下是关于远程监控户外组网的详细分析与应用: 物联网应用场景 …