设计模式行为型——状态模式

 

目录

状态模式的定义

状态模式的实现

状态模式角色

状态模式类图

状态模式举例

状态模式代码实现

状态模式的特点

优点

缺点

使用场景

注意事项

实际应用


       在软件开发过程中,应用程序中的部分对象可能会根据不同的情况做出不同的行为,把这种对象称为有状态的对象,而把影响对象行为的一个或多个动态变化的属性称为状态。当有状态的对象与外部事件产生互动时,其内部状态就会发生改变,从而使其行为也发生改变。如天气都有晴天和雨天的时候,不同的天气有不同的行为,当然天气也会受影响其他影响变化。

状态模式的定义

        状态模式(State Pattern)属于行为型设计模式,也叫作状态机模式(StateMachine Pattern),对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

        状态模式中类的行为是由状态决定的,在不同的状态下有不同的行为。其意图是让一个对象在其内部改变的时候,行为也随之改变。状态模式的核心是状态与行为绑定,不同的状态对应不同的行为。

        在状态模式中,创建表示各种状态的对象和一个行为随着状态对象改变而改变的context对象。

        状态模式的解决思想是:当控制一个对象状态转换的条件表达式过于复杂时,把相关“判断逻辑”提取出来,用各个不同的类进行表示,系统处于哪种情况,直接使用相应的状态类对象进行处理,这样能把原来复杂的逻辑判断简单化,消除了 if-else、switch-case 等冗余语句,代码更有层次性,并且具备良好的扩展力。

状态模式的实现

状态模式角色

  1. 环境类角色(Context):也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
  2. 抽象状态角色(State):定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
  3. 具体状态角色(Concrete State):实现抽象状态所对应的行为,每一个类封装了一个状态对应的行为,并且在需要的情况下进行状态切换。

状态模式类图

状态模式举例

        打篮球的时候运动员可以有正常状态,不正常状态,和超常状态,现在就以我们打篮球时候投篮时候的状态来举例子。正常状态下运动员投十个球进五个球;不正常状态下运动员投十个球进一个球,和超常状态下运动员投十个球进十个球。此时投篮状态为抽象状态角色,运动员的三种投篮竞技状态为具体状态角色,而运动员为环境类角色。

状态模式代码实现

抽象状态角色

package com.common.demo.pattern.state;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 抽象状态角色 投篮* @date 2023/08/07 20:56:20*/
public interface State {/*** 投篮*/void shot();
}

具体状态角色

package com.common.demo.pattern.state;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体状态角色 投篮正常* @date 2023/08/07 21:00:07*/
public class NormalState implements State{@Overridepublic void shot() {System.out.println("发挥正常,十中五");}
}
package com.common.demo.pattern.state;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体状态角色 投篮超常* @date 2023/08/07 21:00:44*/
public class SuperState implements State{@Overridepublic void shot() {System.out.println("发挥超长,十中十");}
}
package com.common.demo.pattern.state;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 具体状态角色 投篮不正常* @date 2023/08/07 20:57:46*/
public class UnnormalState implements State{@Overridepublic void shot() {System.out.println("投篮发挥失常,十中一");}
}

环境类角色

package com.common.demo.pattern.state;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 环境角色 运动员* @date 2023/08/07 21:01:45*/
public class Player {private State state = new NormalState();public void setState(State state) {this.state = state;}public void shot() {state.shot();}
}

测试类

package com.common.demo.pattern.state;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 状态模式测试类* @date 2023/08/07 21:02:30*/
public class StateTest {public static void main(String[] args) {Player player = new Player();player.shot();//正常下投篮player.setState(new UnnormalState());player.shot();//不正常下投篮player.setState(new SuperState());player.shot();//超常下投篮}
}

测试截图

状态模式的特点

优点

  1. 将状态相关的行为封装到具体状态类中:状态模式通过将不同状态的行为封装到具体状态类中,使得状态之间的转换和行为的变化清晰明确。
  2. 遵循开闭原则:新增状态时无需修改原有代码,只需要添加新的状态类和相应的转换逻辑。
  3. 简化了条件判断:状态模式避免了大量的条件判断语句,使得代码更加可读、可维护。
  4. 符合单一职责原则:将特定的状态及其行为都封装到单独的类中。

缺点

  1. 增加了类的数量:使用状态模式会增加多个具体状态类,导致类的数量增加。
  2. 可能造成状态转换的复杂性:如果状态之间的转换逻辑比较复杂,可能会导致状态转换的控制逻辑变得复杂难以维护。
  3. 状态模式对"开闭原则"的支持并不太好:对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

使用场景

  1. 当对象的行为取决于其内部状态,并且在运行时可以动态改变状态时,可以使用状态模式。
  2. 当对象有多个状态且每个状态对应的行为有所不同时,可以使用状态模式。
  3. 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时,可以使用状态模式。

注意事项

  1. 状态之间的转换关系要清晰:确保状态之间的转换关系清晰明确,避免状态转换的混乱和错误。
  2. 借助上下文对象管理状态:状态模式通常需要配合上下文对象来管理状态的转换和行为委托,确保状态的正确切换和行为的正确执行。
  3. 状态最好不要超过5个:在行为受到状态约束的时候,使用状态模式,且状态最好不要超过5个

实际应用

  1. 订单状态管理:订单的生命周期包含多个状态(待支付、已支付、已发货等),可以使用状态模式来管理订单状态的转换和相应的行为。
  2. 状态机:状态机是一种广泛应用于计算机编程中的模型。状态模式可以用于实现复杂的状态机逻辑。
  3. 游戏角色状态:游戏中的角色可以根据不同的状态进行不同的行为,状态模式可以用于管理角色的状态和行为。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

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

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

相关文章

flutter开发实战-实现marquee根据文本长度显示文本跑马灯效果

flutter开发实战-实现marquee文本跑马灯效果 最近开发过程中需要marquee文本跑马灯效果,这里使用到了flutter的插件marquee 效果图如下 一、marquee 1.1 引入marquee 在pubspec.yaml中引入marquee # 跑马灯效果marquee: ^2.2.31.2 marquee使用 marquee使用也是…

谈谈对Spring MVC的理解

问题分析: SpringMVC 是一种基于 Java 语言开发,实现了 Web MVC 设计模式,请求驱动类型 的轻量级 Web 框架。 SpringMVC采用了 MVC 架构模式的思想,通过把 Model,View,Controller 分离,将 Web 层…

易服客工作室:如何在WordPress网站中举办虚拟活动

您是否正在寻找举办和管理虚拟活动的最佳方式? 也许您想在线举行下一次会议或举办有关您的产品和服务的网络研讨会。您可能担心它太贵,或者您没有技术知识来实现​​它。 在本文中,我们将列出您所需的在线服务的所有设备,并教您…

实践指南-前端性能提升 270% | 京东云技术团队

一、背景 当我们疲于开发一个接一个的需求时,很容易忘记去关注网站的性能,到了某一个节点,猛地发现,随着越来越多代码的堆积,网站变得越来越慢。 本文就是从这样的一个背景出发,着手优化网站的前端性能&a…

在R中比较两个矩阵是否相等

目录 方法一:使用all.equal()比较两个R对象是否近似相等 方法二:使用identical比较两个R对象是否精确相等。 方法一:使用all.equal()比较两个R对象是否近似相等 使用函数:all.equal(x,y) 比较两个R对象x和y是否近似相等 > M1…

abbitmq启动访问不了http://localhost:15672 通过修改服务登录admin

abbitmq默认的对Administration授权,而我的用户不是默认的Administration,所以后来打开服务,找到rabbitmq服务,属性,登陆,将本地系统账户修改为此账户,修改完成之后再重启服务,这时候…

SpringMVC注解开发

1. 构建流程 1&#xff09;IDEA创建一个Maven项目。配置所需依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></depe…

【Fegin技术专题】「原生态」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)

前提介绍 Feign是SpringCloud中服务消费端的调用框架&#xff0c;通常与ribbon&#xff0c;hystrix等组合使用。由于遗留原因&#xff0c;某些项目中&#xff0c;整个系统并不是SpringCloud项目&#xff0c;甚至不是Spring项目&#xff0c;而使用者关注的重点仅仅是简化http调…

瑞数系列及顶像二次验证LOGS

瑞数商标局药监局专利局及顶像二次验证 日期&#xff1a;20230808 瑞数信息安全是一个专注于信息安全领域的公司&#xff0c;致力于为企业和个人提供全面的信息安全解决方案。他们的主要业务包括网络安全、数据安全、应用安全、云安全等方面的服务和产品。瑞数信息安全拥有一支…

机器学习笔记:李宏毅chatgpt 大模型 大资料

1 大模型 1.1 大模型的顿悟时刻 Emergent Abilities of Large Language Models&#xff0c;Transactions on Machine Learning Research 2022 模型的效果不是随着模型参数量变多而慢慢变好&#xff0c;而是在某一个瞬间&#xff0c;模型“顿悟”了 这边举的一个例子是&#…

YOLOv5、YOLOv8改进:MobileViT:轻量通用且适合移动端的视觉Transformer

MobileViT: Light-weight, General-purpose, and Mobile-friendly Vision Transformer 论文&#xff1a;https://arxiv.org/abs/2110.02178 1简介 MobileviT是一个用于移动设备的轻量级通用可视化Transformer&#xff0c;据作者介绍&#xff0c;这是第一次基于轻量级CNN网络性…

STM32 LL库+STM32CubeMX--点亮板载LED

一、前期准备 硬件&#xff1a;STM32F103C8T6开发板调试工具&#xff1a;DAPLink(本次使用)或USB-TTL开发环境&#xff1a;STM32CubeMX、Keil、Vscode(可选)板载LED&#xff1a;PC13(低电平点亮) 二、STM32CubeMX配置 1.选择芯片型号&#xff1a; 2.配置外设时钟&#xff1a;…

【BASH】回顾与知识点梳理(十七)

【BASH】回顾与知识点梳理 十七 十七. 什么是 Shell scripts17.1 干嘛学习 shell scripts自动化管理的重要依据追踪与管理系统的重要工作简单入侵检测功能连续指令单一化简易的数据处理跨平台支持与学习历程较短 17.2 第一支 script 的撰写与执行撰写第一支 script 17.3 撰写 s…

Android应用开发(37)LTPO帧率测试基于Surfaceview(暂存)

Android应用开发学习笔记——目录索引 参考android官网&#xff1a; Frame rate | Android media | Android Developers多重刷新率 | Android 开源项目 | Android Open Source ProjectWindowManager.LayoutParams | Android Developers 目前市面上旗舰手机基本都是…

[保研/考研机试] KY56 数制转换 北京大学复试上机题 C++实现

题目链接&#xff1a; 数制转换https://www.nowcoder.com/share/jump/437195121691734210665 描述 求任意两个不同进制非负整数的转换&#xff08;2进制&#xff5e;16进制&#xff09;&#xff0c;所给整数在long所能表达的范围之内。 不同进制的表示符号为&#xff08;0&a…

腾讯云COS的快速接入

背景 最近在研究一个剪贴板粘贴工具&#xff0c;实现粘贴图片&#xff0c;返回可访问的地址&#xff0c;这个在我的哔哩哔哩上有出一期视频&#x1f92d;。但是&#xff0c;我发现部分博客平台不能正常的转载我的图片链接&#xff0c;于是研究了一下腾讯云的COS&#xff08;阿…

Oracle 知识篇+会话级全局临时表在不同连接模式中的表现

标签&#xff1a;会话级临时表、全局临时表、幻读释义&#xff1a;Oracle 全局临时表又叫GTT ★ 结论 ✔ 专用服务器模式&#xff1a;不同应用会话只能访问自己的数据 ✔ 共享服务器模式&#xff1a;不同应用会话只能访问自己的数据 ✔ 数据库驻留连接池模式&#xff1a;不同应…

“冰箭卫士·IP发布会”首次亮相第14届海峡两岸(厦门)文博会

2023年8月6日,“冰箭卫士IP发布会”首次亮相海峡两岸文博会思明馆。此次发布会由厦门市文化创意产业协会、厦门理工&#xff08;集美区&#xff09;政产学研基地主办&#xff0c;厦门市文化创意产业协会IP设计研究院、厦门一笔之上文化发展有限公司、冰箭应急安全科技研究院承办…

(vue)获取对象的键遍历,同时循环el-tab页展示key及内容

(vue)获取对象的键遍历&#xff0c;同时循环el-tab页展示key及内容 效果&#xff1a; 数据结构&#xff1a; "statusData": {"订购广度": [ {"id": 11, "ztName": "广", …

[保研/考研机试] KY183 素数 北京航空航天大学复试上机题 C++实现

题目链接&#xff1a; 素数https://www.nowcoder.com/share/jump/437195121691718444910 描述 输入一个整数n(2<n<10000)&#xff0c;要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数&#xff0c;如果没有则输出-1。 输入描述&#xff1a; 输入有多…