二十三种设计模式第二十三篇--状态模式

状态模式,是一种行为模式,在软件开发过程中,对象按照不同的情况做出不同的行为,我们把这样的对象称为具有状态的对象,而把影响对象行为的一个或者多个动态变化的属性称为状态。

对这种具有状态的对象变成,传统的解决方案是,将这些所有可能发生情况全部考虑到,然后使用if-else或者switch-case语句来做状态判断,再进行不同情况的处理。但是这种情况存在一个弊端,就是,条件判断语句会过于浮肿,可读性差,并且不具备拓展性,维护难度也将加大,并且增加新的状态时需要添加新的if-else语句,这违背了“开闭原则”,并不利于程序的拓展。

状态模式:它允许对象在内部状态改变时改变其行为。状态模式将状态和对应的行为封装成不同的状态对象,使得对象的行为可以根据不同的状态进行动态切换。

状态模式的核心组成部分包括:

状态接口(State Interface):定义了状态对象的接口,包含了对象在该状态下可以执行的方法。

具体状态类(Concrete State):实现了状态接口,在具体的状态下定义了对象的行为。

环境类(Context):包含了一个状态对象,并维护当前的状态,可以根据不同的状态调用相应的方法。

状态模式的主要优点包括:

将状态和行为分离:将不同的状态封装成不同的对象,使得状态和行为可以独立变化,提高了代码的灵活性和可维护性。
简化条件语句:通过状态对象的切换来替代复杂的条件语句,使得代码更加清晰和易懂。
符合开闭原则:增加新的状态类不会修改已有的代码,只需要添加新的状态类和相应的转换规则。

关于状态模式的限制和适用场景:
可能增加对象的数量:每个状态都需要一个对应的状态类,可能会增加对象的数量。
当状态比较少且相对简单时,使用状态模式可能会增加代码的
复杂性。

状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

在这里插入图片描述

/**
 * 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
 */
public interface State {

   //行为动作...
   public void doAction(Context context);

}
/**
 * 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
 * 这里代表游戏玩家开始的状态.
 */
public class StartState implements State {
 
   @Override
   public void doAction(Context context) {
      System.out.println("玩家处理于启动状态,开始相应操作");
      //给上下文对象设定对应的状态对象,然后在 context执行对应的操作
      // 这里避免了使用 if...else 这样的判断语句.
      context.setState(this);
   }
 
   @Override
   public String toString(){
      return "开始状态";
   }
}
/**
 * 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
 *
 * 状态机
 */
public class Context {
   /**
    *  ******* 状态
    */
   private State state;
 
   public Context(){
      state = null;
   }

   //******状态修改
   public void setState(State state){
      this.state = state;
      //TODO:在这里可以加入 状态修改后的进一步的操作...

      //修改状态  -> 触发事件   -> 消息通知   -> 操作  -> 状态改变.
      //    a   ->  e1       ->    b
      //    b   ->   e2      ->    c


   }
 
   public State getState(){
      return state;
   }
}
public class StatePatternDemo {
   public static void main(String[] args) {

      Context context = new Context();
      //注意比较:  以下状态发生变化时,无须要用  if..else做状态判断.

      //设置状态为开始.
      StartState startState = new StartState();
      startState.doAction(context);
 
      System.out.println(context.getState().toString());

      //修改状态为  stop
      StopState stopState = new StopState();
      stopState.doAction(context);
 
      System.out.println(context.getState().toString());
   }
}
/**
 * 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
 * 停止状态
 */
public class StopState implements State {
 
   @Override
   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      //给上下文对象设定对应的状态对象,然后在 context执行对应的操作
      // 这里避免了使用 if...else 这样的判断语句.
      context.setState(this); 
   }
 
   @Override
   public String toString(){
      return "Stop State";
   }
}

路才刚刚开始走,怎么能半路放弃呢?听我所听,做我想做,梦我想梦,也许几年后我看到这句话会把他删掉,也许他就这么挂在这里,一直挂着。我与众生皆为凡人,无高低贵贱,他擅他长,吾擅吾长,何须羡慕他人等?身在其位,专攻其事,如若不善,辞职跑路!何须压抑与心之久,于己不快哉,长路漫漫有人陪同吾亦乐之,无人陪同吾亦独行,彼岸花开,终有一日,吾亦赏之。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

容器技术:Docker搭建(通俗易懂)

目录 Docker搭建环境准备Docker安装1、查看服务器是否安装Docker2、卸载Docker3、安装Dokcer依赖环境4、配置Docker国内阿里云镜像5、安装Docker6、查看Docker信息7、配置阿里云镜像加速8、镜像安装10、运行实例11、查看实例状态12、测试 Docker命令集合 Docker搭建 环境准备 …

【机器学习】对 MLOps 的友好的介绍(MLOps1)

一、说明 我对 MLOps 感兴趣已经有一段时间了。我第一次从机器学习工程师那里了解到它,由于我当时还是一名博士生,我并不知道它的存在。然而,我的好奇心被激起了,我开始了解它。回想起来,我很后悔没有早点了解它&#…

正泰电力携手图扑:VR 变电站事故追忆反演

VR(Virtual Reality,虚拟现实)技术作为近年来快速发展的一项新技术,具有广泛的应用前景,支持融合人工智能、机器学习、大数据等技术,实现更加智能化、个性化的应用。在电力能源领域,VR 技术在高性能计算机和专有设备支…

行政资产管理信息系统

行政资产管理信息系统是通过专业设计开发的资产管理解决方案,旨在为企业建立和完善资产管理体系。该系统可以有效地控制资产的购买和应用,从而节省资金,完成资产的有效管理。   资产管理信息系统的核心功能是统一资产管理,可以…

攻防世界-reverse-logmein

题目描述:菜鸡开始接触一些基本的算法逆向了 下载附件,是一个可执行程序 1. 思路分析 逆向出来看看代码 从代码中来看,密码长度需要和V8相等,并且每一个字符的运算结果需要满足 s[i] (char)(v8[i % v6 - 8] ^ v8[i]) 但是这…

2024年浙财MBA项目招生信息全面了解

2024年全国管理类硕士联考备考已经到了最火热的阶段,不少考生开始持续将注意力集中在备考的规划中!杭州达立易考教育整合浙江省内的MBA项目信息,为大家详细梳理了相关报考参考内容,方便大家更好完成择校以及针对性的备考工作。本期…

有哪些开源和非开源的项目管理工具?

开源和非开源项目管理工具各有其特点和优势。下面是一些常见的开源和非开源项目管理工具以及它们的简要介绍。 开源项目管理工具: OpenProject:OpenProject 是一个功能强大、易于使用的开源项目管理工具。它提供了项目计划、任务管理、团队协作、文档管…

智慧防汛,数字科技的力量

随着夏日的脚步临近,台风季节即将降临。对于那些居住在沿海地区的人们来说,台风是一种常见的自然灾害,其带来的风雨可能对生命和财产造成严重威胁。然而,随着数字科技的飞速发展,可视化技术为防汛抗台工作带来了全新的…

垃圾回收机制和常用的算法

一.什么是垃圾回收? 垃圾回收主要针对堆和方法区(非堆),程序计数器,虚拟机栈,本地方法栈这三个区域属于线程私有,随着线程的销毁,自然就会雄安会了,因此不需要堆着三个区域进行垃圾…

macOS 虚拟桌面黑屏(转)

转自:macOS重置虚拟桌面、macOS 虚拟桌面黑屏 有几次出现如图的情况,以为是iTerm的问题,但是在关闭软件,重启之后,依旧无效。 后面经过网友告知,才知道是虚拟桌面的问题。 为了清理这个问题,有以…

Apache Doris 巨大飞跃:存算分离新架构

作者:马如悦 Apache Doris 创始人 历史上,数据分析需求的不断提升(更大的数据规模、更快的处理速度、更低的使用成本)和计算基础设施的不断进化(从专用的高端硬件、到低成本的商用硬件、到云计算服务)&…

牛客网Verilog刷题——VL56

牛客网Verilog刷题——VL56 题目答案 题目 实现4bit无符号数流水线乘法器设计。电路的接口如下图所示: 输入输出描述: 信号类型输入/输出位宽描述clkwireInput1系统时钟信号rst_nwireInput1异步复位信号,低电平有效mul_awireInputsize乘数mu…

MFC第二十六天 CRgn类简介与开发、封装CMemoryDC类并应用开发

文章目录 CRgn类简介与开发CRgn类简介CRgn类区域管理开发CRgn类区域管理与不规则形状的选取 封装CMemoryDC类并应用开发CMemoryDC.h封装CMemoryDC开发游戏透明动画CFlashDlg.hCFlashDlg.cpp 封装CMemoryDC开发游戏动画 附录四大窗口CDC派生类 CRgn类简介与开发 CRgn类简介 CR…

常微分方程建模R包ecode(二)——绘制相速矢量场

本节中我们考虑一个更为复杂的常微分方程模型, d X C d t ν ( X A Y A ) − β ⋅ X C ⋅ ( Y C Y A ) − ( μ g ) ⋅ X C , ( 1 ) d Y C d t β ⋅ X C ⋅ ( Y C Y A ) − ( μ g ρ ) ⋅ Y C , ( 2 ) d X A d t g ⋅ X C − β ⋅ X A ⋅ ( Y C Y A …

Tcp的粘包和半包问题及解决方案

目录 粘包: 半包: 应用进程如何解读字节流?如何解决粘包和半包问题? ①:固定长度 ②:分隔符 ③:固定长度字段存储内容的长度信息 粘包: 一次接收到多个消息,粘包 应…

利用XSS在线平台获取用户cookie

//XSS弹窗&#xff1a; <script>alert("xss")</script> XSS漏洞&#xff1a; //XSS弹窗&#xff1a; <script>alert("xss")</script> //XSS在线平台&#xff1a; <ScRipT sRc//7ix7kigpovxdbtd32fuspgffmtmufo3wwzgnzaltddewtb…

推荐前端开发者提升效率的工具

是否掌握新的技术很大程度决定着你是否被淘汰。 虽然应用程序试图将网站替代&#xff0c;但前端 Web 开发业务仍在快速变化和增长&#xff0c;前端开发人员的功能并没有消失。以下介绍一款前端开发者提升效率的工具。 目录 一、低代码工具前景 二、如何理解低代码工具 三、前端…

【word技巧】如何做到,批量保存word文档图片

Word文件中有很多图片都需要保存&#xff0c;除了一张张的进行图片另存为以外&#xff0c;我们还有其他方法可以批量一次性保存word文档中的图片嘛&#xff1f;今天分享两个方法&#xff0c;批量保存word文档图片。 方法一&#xff1a; 将文件进行另存为&#xff0c;在选择路…

C++ 用指针处理数组元素

指针加减运算的特点使得指针特别合适于处理存储在一段连续内存空间中的同类数据。而数组恰好是具有一定顺序关系的若干同类型变量的集合体&#xff0c;数组元素的存储在物理上也是连续的&#xff0c;数组名就是数组存储的首地址。这样&#xff0c;便可以使用指针来对数组及其元…

Spring Boot 日志

Spring Boot 日志 ​ 在 Spring Boot 里面是有一个内置了的日志框架的&#xff0c;所以才能运行的时候在控制台打印出来。默认情况下的日志是系统定义和打印的&#xff0c;但我们也可以自行自定义打印日志。 日志的好处&#xff1a; 1、发现问题和定位问题&#xff1b;☆&am…