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

C#设计模式--状态模式(State Pattern)

状态模式是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这种模式的核心思想是将状态封装在独立的对象中,而不是将状态逻辑散布在整个程序中。

用途

  1. 简化复杂的条件逻辑:通过将不同的状态封装在不同的类中,可以避免大量的条件语句,使代码更清晰、更易于维护。
  2. 提高可扩展性:添加新的状态或修改现有状态的行为时,只需修改或新增相应的状态类,而不需要修改现有的代码。
  3. 提高代码的复用性:状态对象可以在多个上下文对象之间共享,提高代码的复用性。
    示例代码及类图

示例1:交通信号灯

public interface ILightState
{void Handle(TrafficLight context);
}public class RedLightState : ILightState
{public void Handle(TrafficLight context){Console.WriteLine("Red Light");context.SetState(new GreenLightState());}
}public class GreenLightState : ILightState
{public void Handle(TrafficLight context){Console.WriteLine("Green Light");context.SetState(new YellowLightState());}
}public class YellowLightState : ILightState
{public void Handle(TrafficLight context){Console.WriteLine("Yellow Light");context.SetState(new RedLightState());}
}public class TrafficLight
{private ILightState _state;public TrafficLight(ILightState initialState){_state = initialState;}public void ChangeLight(){_state.Handle(this);}public void SetState(ILightState state){_state = state;}
}

类图

ILightState
+void Handle(TrafficLight context)
RedLightState
+void Handle(TrafficLight context)
GreenLightState
+void Handle(TrafficLight context)
YellowLightState
+void Handle(TrafficLight context)
TrafficLight
-ILightState _state
+TrafficLight(ILightState initialState)
+void ChangeLight()
+void SetState(ILightState state)

示例2:订单状态管理

public interface IOrderState
{void Handle(Order context);
}public class PendingState : IOrderState
{public void Handle(Order context){Console.WriteLine("Order is pending");context.SetState(new ProcessingState());}
}public class ProcessingState : IOrderState
{public void Handle(Order context){Console.WriteLine("Order is being processed");context.SetState(new ShippedState());}
}public class ShippedState : IOrderState
{public void Handle(Order context){Console.WriteLine("Order has been shipped");context.SetState(new DeliveredState());}
}public class DeliveredState : IOrderState
{public void Handle(Order context){Console.WriteLine("Order has been delivered");}
}public class Order
{private IOrderState _state;public Order(IOrderState initialState){_state = initialState;}public void Process(){_state.Handle(this);}public void SetState(IOrderState state){_state = state;}
}

类图

IOrderState
+void Handle(Order context)
PendingState
+void Handle(Order context)
ProcessingState
+void Handle(Order context)
ShippedState
+void Handle(Order context)
DeliveredState
+void Handle(Order context)
Order
-IOrderState _state
+Order(IOrderState initialState)
+void Process()
+void SetState(IOrderState state)

示例3:游戏角色状态

public interface ICharacterState
{void Handle(Character context);
}public class IdleState : ICharacterState
{public void Handle(Character context){Console.WriteLine("Character is idle");context.SetState(new WalkingState());}
}public class WalkingState : ICharacterState
{public void Handle(Character context){Console.WriteLine("Character is walking");context.SetState(new RunningState());}
}public class RunningState : ICharacterState
{public void Handle(Character context){Console.WriteLine("Character is running");context.SetState(new IdleState());}
}public class Character
{private ICharacterState _state;public Character(ICharacterState initialState){_state = initialState;}public void Move(){_state.Handle(this);}public void SetState(ICharacterState state){_state = state;}
}

类图

ICharacterState
+void Handle(Character context)
IdleState
+void Handle(Character context)
WalkingState
+void Handle(Character context)
RunningState
+void Handle(Character context)
Character
-ICharacterState _state
+Character(ICharacterState initialState)
+void Move()
+void SetState(ICharacterState state)

代码解析

  1. 状态接口 (IState):定义了一个 Handle 方法,所有具体状态类都需要实现这个方法。
  2. 具体状态 (StateAStateB):实现了 IState 接口,具体实现了 Handle 方法。在处理完当前状态后,可以改变上下文的当前状态。
  3. 上下文类 (Context):维护一个对当前状态的引用,并提供一个方法 Request 来调用当前状态的 Handle 方法。上下文还提供了一个属性 State 来改变当前状态,并在状态改变时输出相关信息。

优点

  1. 简化条件逻辑:通过将状态逻辑封装在不同的类中,减少了大量的条件语句,使代码更清晰、更易于维护。
  2. 提高可扩展性:添加新的状态或修改现有状态的行为时,只需修改或新增相应的状态类,而不需要修改现有的代码。
  3. 提高代码的复用性:状态对象可以在多个上下文对象之间共享,提高代码的复用性。

缺点

  1. 增加类的数量:每种状态都需要一个类,这可能会导致类的数量增多,增加系统的复杂性。
  2. 状态转换逻辑分散:状态转换的逻辑分布在不同的状态类中,有时可能难以追踪和理解。
  3. 过度设计:对于简单的状态转换,使用状态模式可能会显得过于复杂,增加不必要的开销。

总结

状态模式适用于需要管理多种状态和状态转换的场景,特别是在状态逻辑较为复杂的情况下。通过将状态逻辑封装在独立的类中,可以使代码更加模块化、易于维护和扩展。然而,在简单的情况下,使用状态模式可能会增加不必要的复杂性。

相关文章:

C#设计模式--状态模式(State Pattern)

状态模式是一种行为设计模式,它允许对象在其内部状态发生变化时改变其行为。这种模式的核心思想是将状态封装在独立的对象中,而不是将状态逻辑散布在整个程序中。 用途 简化复杂的条件逻辑:通过将不同的状态封装在不同的类中,可…...

〔 MySQL 〕索引

目录 1. 没有索引,可能会有什么问题 2. 认识磁盘 MySQL与存储 先来研究一下磁盘: 在看看磁盘中一个盘片​编辑 扇区 定位扇区​编辑 结论 磁盘随机访问(Random Access)与连续访问(Sequential Access) 3. MySQL 与磁盘交互基本单位 4. 建立共识…...

计算机网络研究实训室建设方案

一、概述 本方案旨在规划并实施一个先进的计算机网络研究实训室,旨在为学生提供一个深入学习、实践和研究网络技术的平台。实训室将集教学、实验、研究于一体,覆盖网络基础、网络架构、网络安全、网络管理等多个领域,以培养具备扎实理论基础…...

韩企研学团造访图为科技:共探人工智能创新前沿

今日,一支由韩国知名企业研学专家组成的代表团莅临图为科技深圳总部,展开了一场深度技术交流与研讨活动。 此次访问旨在通过实地探访中国领先的科技企业,促进中韩两国在科技创新领域的深入合作与交流。 韩国游学团合影 图为科技作为一家在人…...

html button 按钮单选且 高亮

<DIV class"middle"> <div class"containerTarget"> <span class"hover-target1" οnclick"btn(1);">韵达 </span> <span class"hover-target2" οnclick"btn(2);">中通 </span…...

图片上传HTML

alioss sky:jwt:# 设置jwt签名加密时使用的秘钥admin-secret-key: itcast# 设置jwt过期时间admin-ttl: 7200000# 设置前端传递过来的令牌名称admin-token-name: tokenalioss:endpoint: ${sky.alioss.endpoint}access-key-id: ${sky.alioss.access-key-id}access-key-secret: $…...

C++学习-函数

C 函数 目录 函数默认参数引用传参函数重载 数量不同类型不同 内联函数 函数默认参数 #include<iostream>using std::cout; using std::endl;int power(int n, int x2); // x2 是默认参数int main() {cout << power(5) << endl; // 没有传 x 的值&#x…...

spring boot 测试 mybatis mapper类

spring boot 测试 mybatis mapper类 针对 mybatis plus不启动 webserver指定加载 xml 【过滤 “classpath*:/mapper/**/*.xml” 下的xml】, mapper xml文件名和mapper java文件名称要一样&#xff0c;是根据文件名称过滤的。默认情况加载和解析所有mapper.xml 自定义 MapperT…...

远程游戏新体验!

在这个数字化的时代&#xff0c;游戏已经不仅限于家里的电视或书房的电脑了。远程游戏&#xff0c;也就是通过远程控制软件在不同地点操作游戏设备&#xff0c;给玩家带来了前所未有的自由和灵活性。RayLink远程控制软件&#xff0c;凭借其出色的性能和专为游戏设计的功能&…...

Let up bring up a linux.part2 [十一]

之前的篇幅中我们已经将 Linux 内核 bringup 起来了&#xff0c;不知道大家有没有去尝试将根文件系统运行起来&#xff0c;今天我就带领大家完成这个事情&#xff0c;可以跟着下面的步骤一步步来完成&#xff1a; 在这里我们使用 busybox 构建 rootfs&#xff1a; 下载 busyb…...

调用大模型api 批量处理图像 保存到excel

最近需要调用大模型&#xff0c;并将结果保存到excel中&#xff0c;效果如下&#xff1a; 代码&#xff1a; import base64 from zhipuai import ZhipuAI import os import pandas as pd from openpyxl import Workbook from openpyxl.drawing.image import Image from io i…...

使用 Flownex 模拟热环境对原油运输的影响

石油和天然气行业经常使用管道仿真来模拟原油的流动。为了准确估计管道容量&#xff0c;必须考虑环境对管道的热影响以及环境温度如何影响油品特性。本博客介绍了如何通过将传热元件集成到管道流网中&#xff0c;以及使用新的工作液材料 Flownex 来模拟各种传热机制。 使用 Fl…...

【WRF-Urban】WPS中有关Urban的变量设置

【WRF-Urban】WPS中有关Urban的变量设置 地理数据源的配置WRF-Urban所需静态地理数据1、LANDUSE:包含城市地表分类的土地利用数据。2、URB_PARAM:城市参数数据集。3、FRC_URB2D:城市覆盖度数据集WRF默认设置(美国)数据集1-National urban dataset in China NUDC(中国)数…...

Socket编程-tcp

1. 前言 在tcp套接字编程这里&#xff0c;我们将完成两份代码&#xff0c;一份是基于tcp实现普通的对话&#xff0c;另一份加上业务&#xff0c;client输入要执行的命令&#xff0c;server将执行结果返回给client 2. tcp_echo_server 与udp类似&#xff0c;前两步&#xff1…...

Redis 之持久化

目录 介绍 RDB RDB生成方式 自动触发 手动触发 AOF&#xff08;append-only file&#xff09; Redis 4.0 混合持久化 Redis主从工作原理 总结 介绍 Redis提供了两个持久化数据的能力&#xff0c;RDB Snapshot 和 AOF&#xff08;Append Only FIle&#xff09;…...

视频监控汇聚平台:Liveweb安防监控平台实现接入监控视频集中管理方案

随着各行业数字化转型的不断推进&#xff0c;视频监控技术在行业内的安防应用及管理支撑日益增多。然而&#xff0c;由于前期规划不清晰、管理不到位等问题&#xff0c;视频监管系统普遍存在以下问题&#xff1a; 1. 各部门单位在视频平台建设中以所属领域为单位&#xff0c;导…...

ABAP - 系统集成之SAP的数据同步到OA(泛微E9)服务器数据库

需求背景 项目经理说每次OA下单都需要调用一次SAP的接口获取数据&#xff0c;导致效率太慢了&#xff0c;能否把SAP的数据保存到OA的数据库表里&#xff0c;这样OA可以直接从数据库表里获取数据效率快很多。思来想去&#xff0c;提供了两个方案。 在集群SAP节点下增加一个SQL S…...

uniapp使用ucharts修改Y、X轴标题超出换行

找到ucharts里面的u-charts.js。 Y轴的话找到drawYAxis方法。然后找到方法里面绘制文字的context.fillText方法。先把这个代码注释掉&#xff0c;然后加上下面代码 let labelLines item.split(\n); let currentY pos yAxisFontSize / 2 - 3 * opts.pix; labelLines.forEac…...

三分钟详细解读什么是Ecovadis认证?

Ecovadis认证&#xff0c;这一源自法国的全球性企业可持续性评估体系&#xff0c;宛如一面明镜&#xff0c;映照出企业在环境、社会和治理&#xff08;ESG&#xff09;领域的真实面貌。它不仅仅是一项简单的认证&#xff0c;更是一个推动全球企业和供应链向更加绿色、公正、透明…...

spring6:4、原理-手写IoC

目录 4、原理-手写IoC4.1、回顾Java反射4.2、实现Spring的IoC 4、原理-手写IoC 我们都知道&#xff0c;Spring框架的IOC是基于Java反射机制实现的&#xff0c;下面我们先回顾一下java反射。 4.1、回顾Java反射 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#x…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...