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

c#设计模式-行为型模式 之 状态模式

🚀简介

状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,我们可以通过创建一个状态接口和一些实现了该接口的状态类来实现状态模式。然后,我们可以创建一个上下文类,它会根据其当前的状态对象来改变其行为。

状态模式包含以下主要角色。
  1. 环境(Context)角色:也称为上下文,它定义了客户程序需要的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
  2. 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
  3. 具体状态(Concrete State)角色:实现抽象状态所对应的行为。

🚀案例

🐤抽象状态

public interface IState
{void Handle(Context context);
}

🐤具体状态

ConcreteStateA和ConcreteStateB,它们都实现了IState接口。

IState接口定义了一个Handle方法,这个方法接受一个Context对象作为参数。Context对象持有当前的状态。

在ConcreteStateA的Handle方法中,它将Context的状态改变为ConcreteStateB。同样,在ConcreteStateB的Handle方法中,它将Context的状态改变为ConcreteStateA。

这样,Context对象的状态就在ConcreteStateA和ConcreteStateB之间不断切换。

这就是状态模式的基本思想:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

public class ConcreteStateA : IState
{public void Handle(Context context){context.State = new ConcreteStateB();}
}public class ConcreteStateB : IState
{public void Handle(Context context){context.State = new ConcreteStateA();}
}

🐤环境角色 

环境角色有时候也被称为上下文角色,它定义了客户端需要的接口,并且维护一个具体状态角色的实例,这个实例定义当前状态。

在这个类中,首先定义了一个私有的IState类型的_state变量,用于存储当前的状态。

然后,定义了一个构造函数,接收一个IState类型的参数,用于初始化_state变量。

接着,定义了一个公有的State属性,用于获取或设置_state变量的值。在设置_state变量的值时,会输出当前状态的类型名。

最后,定义了一个名为Request的方法,该方法会调用_state变量的Handle方法,用于处理请求。这个方法的参数是当前的Context实例,这样就可以在Handle方法中改变当前的状态。

public class Context
{private IState _state;// Constructorpublic Context(IState state){this.State = state;}// Gets or sets the statepublic IState State{get { return _state; }set{_state = value;Console.WriteLine("State: " + _state.GetType().Name);}}public void Request(){_state.Handle(this);}
}

🐤测试

class MyClass
{public static void Main(string[] args){Context context = new Context(new ConcreteStateA());// 不断地进行请求,同时更改状态context.Request();context.Request();context.Request();context.Request();}
}

运行结果:

在测试类中,我们创建了一个Context对象,并给它设置了初始状态ConcreteStateA。然后我们连续调用四次context.Request()方法。由于ConcreteStateAConcreteStateB在处理请求后会互相转换,所以输出结果会是A、B、A、B的交替出现。

🚀优缺点

优点:
  1. 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
  2. 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
缺点:
  1. 状态模式的使用必然会增加系统类和对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
  3. 状态模式对"开闭原则"的支持并不太好。

使用场景:

  1. 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。
  2. 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。

相关文章:

c#设计模式-行为型模式 之 状态模式

🚀简介 状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,我们可以通过创建一个状态接口和一些实现了该接口的状态类来实现状态模式。然后,我们可以创建一个上下文类,它会根据其当前的状态对象来改…...

使用Docker安装JupyterHub

安装JupyterHub 拉取Jupyter镜像并运行容器 docker run -d -p 8000:8000 --name jupyterhub jupyterhub/jupyterhub jupyterhub # -d:后台运行 # -p 8000:8000:宿主机的8000端口映射容器中的8000端口 # --name jupyterhub:给运行的容器起名…...

SpringCloudGateway网关整合swagger3+Knife4j3,basePath丢失请求404问题

在集成 Spring Cloud Gateway 网关的时候,会出现没有 basePath 的情况,例如定义的 /jeeplus-auth、/jeeplus-system 等微服务前缀导致访问接口404: maven依赖: swagger2于17年停止维护,现在最新的版本为 Swagger3&am…...

html通过使用图像源的协议(protocol)相对 URL 来防止安全/不安全错误

有人知道使用 protocol relative URLs 是否有问题吗&#xff1f;用于图像源以防止混合内容安全警告。 例如链接一张图片: <img src"//domain.com/img.jpg" /> 代替: <img src"http://domain.com/img.jpg" /> or <img src"https…...

【SpringBoot】| Thymeleaf 模板引擎

目录 Thymeleaf 模板引擎 1. 第一个例子 2. 表达式 ①标准变量表达式 ②选择变量表达式&#xff08;星号变量表达式&#xff09; ③链接表达式&#xff08;URL表达式&#xff09; 3. Thymeleaf的属性 ①th:action ②th:method ③th:href ④th:src ⑤th:text ⑥th:…...

Vue Router的进阶

进阶 导航守卫 官方文档上面描述的会比较深奥&#xff0c;而守卫类型也比较多&#xff0c;其中包含了全局前置守卫、全局解析守卫、全局后置钩子、路由独享守卫、组件内守卫。每一种守卫的作用和用法都不相同。这会使得大家去学习的时候觉得比较困难&#xff0c;这边主要介绍…...

方案:快递站智能视频监控3大亮点汇总

快递站智能视频监控方案是一种利用先进的技术和设备&#xff0c;来提升快递站安全管理和快递流程监控的解决方案。具体包括哪些方面呢&#xff1f;今天小编就带大家来看看&#xff01; 1、视频监控系统 在快递站的关键区域安装旭帆科技高清摄像头&#xff0c;如快递仓库、操作…...

Direct3D网格

创建网格 我们可以用D3DXCreateMeshFVF函数创建一个"空"网格对象 &#xff0c;空网格对象是指我们指定了网格的面片总数和顶点总数&#xff0c;然后由该函数为顶点缓存、索引缓存和属性缓存分配大小合适的内存&#xff0c;之后即可手工填入网格数据。 HRESULT WINA…...

docker安装wiki

1.docker pull mediawiki 2.docker run -d --name mywiki -p 8666:80 mediawiki 访问ip:8666,就可以看到配置页面了 3.docker pull mysql docker run -d --name my-mysql -e MYSQL_ROOT_PASSWORD123456 -p 3307:3306 mysql 4.在配置页面链接ip:3307,连接数据库&#xff0c;接下…...

bigemap在林业勘测规划设计行业的一些应用

选择Bigemap的原因&#xff1a; 主要注重影像的时效性&#xff0c;软件的影像时效性比其他的更新快&#xff0c;更清晰。 使用场景&#xff1a; 1.林业督查&#xff0c;主要是根据国家下发的图斑&#xff0c;结合测绘局的影像以及bigemap的较新影像对比去年和今年的林地变化。…...

设计模式学习

文章目录 前言设计模式的七大原则单一职责原则开放封闭原则里氏替换原则依赖倒转原则接口隔离原则合成复用原则迪米特原则总结 GoF二十三种设计模式创建型模式&#xff08;五种&#xff09;结构型模式&#xff08;七种&#xff09;行为型模式&#xff08;十一种&#xff09; 游…...

Openfire身份认证绕过漏洞

漏洞详情&#xff1a; Openfire是采用Java编程语言开发的实时协作服务器&#xff0c;Openfire的管理控制台是一个基于Web的应用程序&#xff0c;被发现可以使用路径遍历的方式绕过权限校验。未经身份验证的用户可以访问Openfire管理控制台中的后台页面。同时由于Openfire管理控…...

类目体系设计总结

一、背景 公司窗帘产品在做分类调整&#xff0c;从原先二级类目调整为三级类目&#xff0c;相对于平台电商我们的类目层次结构要简单很多&#xff08;没有定义商品动态属性等&#xff09;&#xff0c;但对于也有上万款SKU的系统来讲,做好基础的分类对于采购、商品促销、数据报…...

gRPC之proto数据验证

1、proto数据验证 本篇将介绍grpc_validator&#xff0c;它可以对gRPC数据的输入和输出进行验证。 这里复用上一篇文章的代码。 1.1 创建proto文件&#xff0c;添加验证规则 这里使用第三方插件go-proto-validators 自动生成验证规则。 地址&#xff1a;https://github.co…...

计算机竞赛 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…...

css--踩坑

1. 子元素的宽高不生效问题 设置flex布局后&#xff0c;子元素的宽高不生效问题。 如果希望子元素的宽高生效&#xff0c;解决方法&#xff0c;给子元素添加如下属性&#xff1a; flex-shrink: 0; flex-shrink: 0;2. 横向滚动&#xff08;子元素宽度不固定&#xff09; /* tab…...

C超市商品信息查询系统

一、系统界面介绍 1. 超市商品信息查询系统 1、显示商品信息&#xff0c;包括&#xff1a;商品名称、商品种类&#xff08;休闲食品、奶品水饮、生鲜水果&#xff09;、商品价格、商品保质期、商品生产日期&#xff1b; 2、从文件中导入数据、显示、排序、查询的功能。&…...

黑马JVM总结(二十七)

&#xff08;1&#xff09;synchronized代码块 synchronized代码块的底层原理&#xff0c;它是给一个对象进行一个加锁操作&#xff0c;它是如何保证如果你出现了synchronized代码块中出现了问题&#xff0c;它需要给这个对象有一个正确的解锁操作呢&#xff0c;加锁解锁是成对…...

软件测试/测试开发丨Python异常处理 学习笔记

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27722 异常处理 编写程序时&#xff0c;即使语句或表达式使用了正确的语法&#xff0c;执行时仍可能触发错误。执行时检测到的错误称为异常&#xff0c;大…...

026 - STM32学习笔记 - 液晶屏控制(三) - DMA2D快速绘制矩形、直线

026- STM32学习笔记 - 液晶屏控制&#xff08;三&#xff09; - DMA2D快速绘制矩形、直线等 上节直接操作LTDC在先视频上直接显示&#xff0c;我们直接操作显存地址空间中的内容&#xff0c;用来显示图形&#xff0c;但是相对来说&#xff0c;这种方法费时费力&#xff0c;这节…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...

MLP实战二:MLP 实现图像数字多分类

任务 实战&#xff08;二&#xff09;&#xff1a;MLP 实现图像多分类 基于 mnist 数据集&#xff0c;建立 mlp 模型&#xff0c;实现 0-9 数字的十分类 task: 1、实现 mnist 数据载入&#xff0c;可视化图形数字&#xff1b; 2、完成数据预处理&#xff1a;图像数据维度转换与…...