设计模式 20 状态模式

设计模式 20

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • 设计模式 20
    • 状态模式(State Pattern)
      • 1 定义
      • 2 结构
      • 3 示例代码
      • 6 特点
      • 7 适用场景
      • 8 总结

状态模式(State Pattern)

1 定义

状态模式的核心思想是将与状态相关的行为封装在独立的状态对象中,并通过状态对象来管理对象的状态转换。这样,原始对象在其状态发生变化时,会自动切换到对应的状态对象,从而表现出不同的行为。

2 结构

状态模式包含以下角色:

  • 上下文(Context): 维护一个当前状态,并在状态发生变化时,切换到新的状态对象。上下文对象向客户端暴露接口,但行为的实现由状态对象负责。
  • 状态接口(State): 定义状态的接口,声明在该状态下对象可以执行的行为。
  • 具体状态(ConcreteState): 实现状态接口,定义该状态下的具体行为。当上下文处于此状态时,行为由具体状态对象执行。

UML 类图

+-------------------+       +-----------------------------------+
|      Context      |       |       State                       |
+-------------------+       +-----------------------------------+
| - state: State    |<------| + Handle(context: Context): void  |
| + Request(): void |       +-----------------------------------+
+-------------------+            ^                     ^|                     ||                     |+-----------------------------------+        +-----------------------------------+| ConcreteStateA                    |        | ConcreteStateB                    |+-----------------------------------+        +-----------------------------------+| + Handle(context: Context): void  |        | + Handle(context: Context): void  |+-----------------------------------+        +-----------------------------------+

3 示例代码

假设我们要实现一个简单的电灯开关系统,电灯可以处于“开”和“关”两种状态,并且根据当前的状态来执行不同的操作。

状态接口

// 状态接口
public interface IState
{void Handle(Context context);
}

具体状态类

// 具体状态 - 开灯状态
public class OnState : IState
{public void Handle(Context context){Console.WriteLine("The light is already ON.");context.SetState(new OffState());}
}// 具体状态 - 关灯状态
public class OffState : IState
{public void Handle(Context context){Console.WriteLine("The light is OFF. Turning it ON.");context.SetState(new OnState());}
}

上下文类

// 上下文类
public class Context
{private IState _state;public Context(IState state){_state = state;}public void SetState(IState state){_state = state;}public void Request(){_state.Handle(this);}
}

客户端代码

class Program
{static void Main(string[] args){Context context = new Context(new OffState());// 初始状态为关灯状态context.Request(); // 关灯 -> 开灯// 再次请求context.Request(); // 开灯 -> 关灯// 再次请求context.Request(); // 关灯 -> 开灯}
}

运行结果

The light is OFF. Turning it ON.
The light is already ON.
The light is OFF. Turning it ON.

在这个例子中,Context 类维护一个当前状态,当调用 Request() 方法时,会根据当前状态执行相应的操作并切换到下一个状态。OnStateOffState 是两种具体的状态类,分别定义了在不同状态下的行为。

6 特点

  • 优点:

    • 减少复杂性: 通过将状态相关的行为封装在独立的状态对象中,状态模式消除了大量的条件分支语句,使代码更加清晰和易于维护。

    • 状态转换灵活: 可以很容易地添加、删除或修改状态对象,扩展系统的功能,而无需修改上下文类。

    • 符合单一职责原则: 状态模式将与状态相关的行为封装在不同的状态类中,使得每个类只负责一种状态的行为,简化了代码的管理。

  • 缺点:

    • 增加类的数量: 每个状态都需要定义一个具体的状态类,当状态过多时,可能会导致类的数量急剧增加,增加系统的复杂性。

    • 状态之间的依赖: 如果状态之间存在复杂的依赖关系,可能会导致状态之间的转换逻辑变得复杂,难以维护。

7 适用场景

  • 对象的行为依赖于其状态: 当一个对象的行为依赖于其状态,并且它的状态会在运行时改变时,状态模式非常适用。
  • 状态逻辑复杂: 当状态转换的逻辑非常复杂,或者状态之间的转换规则经常变化时,状态模式能够有效地管理这些逻辑。
  • 消除条件分支: 如果代码中存在大量的条件分支语句来处理不同的状态,状态模式可以通过将状态逻辑分散到不同的状态类中来简化代码。

8 总结

状态模式通过将状态相关的行为封装在独立的状态对象中,简化了对象的状态管理逻辑。它消除了大量的条件分支语句,使代码更加清晰和易于扩展。尽管状态模式可能会增加类的数量,但它为管理复杂的状态转换逻辑提供了一种灵活且有效的解决方案。

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

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

相关文章

2. Python之注释及缩进以及print和input函数使用

一. Python代码中的注释及缩进 Python中注释有单行注释&#xff0c;多行注释&#xff0c;声明注释 单行注释使用符号#&#xff0c;从#开始&#xff0c;后面到本行末尾都是注释内容。多行注释可以使用’‘’ ‘’三个引号&#xff0c;三个引号内的内容都是注释声明注释&#x…

解决:Module build failed (from ./node_modules/sass-loader/dist/cjs.js)问题

一、问题 Module build failed (from ./node_modules/sass-loader/dist/cjs.js): Error: Cannot find module sass 二、解决方法 1.清除缓存 npm cache clean --force2.重构项目 npm install 3.更新&#xff08;获取最新的&#xff09;node-sass和sass-loader依赖包 npm …

JumpServer 审计录像的存储与播放

录像文件存储 1、查看 JumpServer 持久化目录配置 开打 JumpServer 配置文件 config.txt&#xff0c;默认路径为 /opt/jumpserver/config 查看系统配置的持久化目录&#xff0c;默认为 /data/jumpserver&#xff0c;平台日常产生的所有日志&#xff0c;录像都将存放在该目录下…

MySQL数据库启用安全审计功能5.7版本

MySQL数据库启用安全审计功能5.7版本&#xff0c;需要使用插件server_audit.dllmysql安装是没有自带这个插件的需要去下载&#xff0c;也可以使用我上传的 操作步骤&#xff1a; 1.把插件复制放到自己安装的mysql下的插件位置&#xff1a;比如我的 C:\zz\ProgramFiles\MySQL\…

HarmonyOs 应用基础--ArkTS-核心-基础

目录 八. ArkTS-语句-类型进阶与渲染控制 1. 对象进阶 1.1. 定义对象数组 1.2. 使用对象数组 2. 渲染控制 - ForEach 2.1. ForEach语法 2.2. ForEach使用优化代码 2.3. 案例-学生档案 实现思路 3. Math对象 4. 综合案例 -- 抽奖卡案例 4.1. 初始页面布局&#xff08;静…

通信工程学习:什么是GSMP通用交换机管理协议

GSMP&#xff1a;通用交换机管理协议 GSMP&#xff08;General Switch Management Protocol&#xff0c;通用交换机管理协议&#xff09;是一种用于IP交换机对ATM交换机进行控制的协议。以下是对GSMP的详细解释&#xff1a; 一、定义与概述 GSMP是一种异步协议&#xff0c;它在…

【JavaSE】基础学习以及简单的计算器应用程序GUI实现

计算机中的二进制 在计算机中&#xff0c;二进制表示是指使用两种状态来表示数字、字符或其他数据。计算机只能处理0和1&#xff0c;因为它们可以通过物理设备的两种状态&#xff08;如高电压或低电压&#xff09;来表示。二进制数的每一位称为一个bit&#xff0c;而八位称为一…

在国产芯片上实现YOLOv5/v8图像AI识别-【4.4】RK3588网络摄像头推理后推流到RTSP更多内容见视频

本专栏主要是提供一种国产化图像识别的解决方案&#xff0c;专栏中实现了YOLOv5/v8在国产化芯片上的使用部署&#xff0c;并可以实现网页端实时查看。根据自己的具体需求可以直接产品化部署使用。 B站配套视频&#xff1a;https://www.bilibili.com/video/BV1or421T74f 前言…

React(v18)事件原理

1. 背景 在旧版 React 中&#xff0c;事件的处理方式不完全符合标准的事件流顺序。事件的处理顺序是&#xff1a; 事件监听&#xff08;比如通过 addEventListener 注册的事件&#xff09;捕获阶段的事件处理&#xff08;即从父元素到子元素的处理&#xff09;冒泡阶段的事件…

【论文阅读】01-Survey on Temporal Knowledge Graph

原文名称&#xff1a;Survey on Temporal Knowledge Graph 1 Introduction 目前有两种方法:基于距离模型的嵌入变换方法和基于语义匹配模型的双线性模型。它们的思想都是将包含实体和关系的知识图谱嵌入到连续的低纬度实向量空间中 时间知识图的推理有两种&#xff0c;第一种是…

斐纳切数列考试题

计算机二级考试有一道题 result [] a,b0,1 while a<100:print(a,end,) a, b b, ab # 0,1,1,2,3,5,8,13,21,34,55,89,

python爬虫代理ip池搭建

最近大量爬取数据的时候总会遇到被封ip的情况&#xff0c;所有打算自己搭建一个代理ip池来使用。本次使用的是开源的ip代理池项目ProxyPool 1.下载redis数据库 redis安装 这里我选择直接下载redis的解压包形式&#xff0c;方便安装。下载地址&#xff1a;发布 TPORADOWSKI/RED…

小型公司机房运维如何管理

本人从业五年&#xff0c;基本是中小型公司。经手的机房也基本是从0-1。今天浅谈一下如果管理小型公司的机房。 机房管理&#xff0c;一般分成以下几个方面&#xff1a; 1、环境管理&#xff1a;比如弱电、强点线路是否排列整齐&#xff1b;机柜门是否做到全部关闭&#xff1b…

SCAU算法竞赛入门指北

首先&#xff0c;还是欢迎各位小朋友来到华南农业大学&#xff0c;虽然不是什么ACM强校&#xff0c;但是姑且还是有这么个校队存在的。本文的主要目的是给各位OI✌️介绍下acm和oi的区别&#xff0c;给各位纯萌新介绍下你需要做什么&#xff0c;以及进校队的时间线。 ACM是什么…

UE4_后期处理_后期处理材质及后期处理体积二

效果&#xff1a; 步骤&#xff1a; 1、创建后期处理材质,并设置参数。 2、回到主界面&#xff0c;找到需要发光的物体的细节面板。 渲染自定义深度通道&#xff0c;默认自定义深度模具值为10&#xff08;需要修改此值&#xff0c;此值影响物体的亮度&#xff09;。 3、添加…

JVM系列(六) -对象的创建过程

一、摘要 在之前的文章中,我们介绍了类加载的过程和 JVM 内存布局相关的知识。本篇我们综合之前的知识,结合代码一起推演一下对象的真实创建过程,以及对象创建完成之后在 JVM 中是如何保存的。 二、对象的创建 在 Java 中,创建对象的方式有很多种,比如最常见的通过new …

Spring 循环依赖原理及解决方案

一、什么是循环依赖 循环依赖指的是一个实例或多个实例存在相互依赖的关系&#xff08;类之间循环嵌套引用&#xff09;。 举例&#xff1a; Component public class AService {// A中注入了BAutowiredprivate BService bService; }Component public class BService {// B中也…

Redis 的标准使用规范之数据类型使用规范

数据类型使用规范 提示&#xff1a;以下是本篇文章正文内容&#xff0c;可供参考 (1)、字符文本&#xff08;STRING&#xff09; 【建议】选型为简易文本类缓存 &#xff1a;比如普通的字符、文本、Json 结构 &#xff0c;通常能起到加速读写和降低后端压力的作用。 【建议】…

数据库系统 第46节 数据库版本控制

数据库版本控制是确保数据库架构和数据模型随着时间的推移而正确演进的重要实践。它允许开发团队跟踪数据库的变更历史&#xff0c;回滚到以前的版本&#xff0c;以及在不同环境&#xff08;如开发、测试和生产环境&#xff09;之间同步数据库结构。以下是两种主要的数据库版本…

ActiveMQ 的网络连接及消息回流机制

1、ActiveMQ 的网络连接 activeMQ 如果要实现扩展性和高可用性的要求的话&#xff0c;就需要用用到网络连接模式。 NetworkConnector&#xff1a;主要用来配置 broker 与 broker 之间的通信连接 如上图所示&#xff0c;MQ 服务器1 和MQ 服务器2 通过 NewworkConnector 相连&…