状态模式:对象状态的变化

欢迎来到设计模式系列的第十七篇文章。在本文中,我们将深入探讨状态模式,这是一种行为型设计模式,用于管理对象的状态以及状态之间的变化。

什么是状态模式?

状态模式是一种允许对象在内部状态发生变化时改变其行为的设计模式。它将对象的状态封装为不同的状态类,并允许对象在运行时切换状态,从而改变其行为。

状态模式有助于将复杂的条件分支语句转化为对象组合。它使得每个状态都可以独立进行测试和维护,提高了代码的可维护性和可扩展性。

状态模式的组成部分

状态模式包括以下主要组成部分:

  1. 上下文(Context): 定义了一个维护状态的对象,并在状态之间切换。上下文可以根据当前状态来改变行为。
  2. 抽象状态(State): 定义了一个接口或抽象类,用于表示状态。具体状态类将实现这个接口,并提供状态特定的行为。
  3. 具体状态(Concrete State): 实现了抽象状态接口,表示不同的状态,并提供了状态下的行为。

状态模式示例

让我们通过一个简单的电梯控制器示例来理解状态模式。假设我们有一个电梯,它可以处于三种状态:打开状态、关闭状态和运行状态。不同的状态下,电梯有不同的行为。

首先,我们定义抽象状态接口 State

public interface State {void open();void close();void run();
}

然后,我们创建具体状态类,例如 OpenStateCloseStateRunState,它们分别表示打开状态、关闭状态和运行状态,并实现了 State 接口:

public class OpenState implements State {public void open() {System.out.println("电梯门已经打开...");}public void close() {System.out.println("电梯门关闭。");}public void run() {System.out.println("电梯开始运行。");}
}public class CloseState implements State {public void open() {System.out.println("电梯门打开。");}public void close() {System.out.println("电梯门已经关闭...");}public void run() {System.out.println("电梯开始运行。");}
}public class RunState implements State {public void open() {System.out.println("电梯门打开。");}public void close() {System.out.println("电梯门关闭。");}public void run() {System.out.println("电梯已经在运行中...");}
}

接下来,我们创建上下文类 Context,它维护当前的状态并委托状态对象来处理行为:

public class Context {private State currentState;public void setState(State state) {this.currentState = state;}public void open() {currentState.open();}public void close() {currentState.close();}public void run() {currentState.run();}
}

现在,我们可以使用状态模式来控制电梯的行为:

public class Client {public static void main(String[] args) {Context context = new Context();State openState = new OpenState();State closeState = new CloseState();State runState = new RunState();context.setState(openState);context.open();context.setState(closeState);context.close();context.setState(runState);context.run();}
}

状态模式的优点和适用场景

状态模式的优点包括:

  • 清晰的状态切换:将状态封装到独立的类中,使状态切换变得清晰明了。
  • 减少条件语句:避免了大量的条件语句,提高了代码的可读性和可维护性。
  • 开放封闭原则:可以轻松地添加新的状态类,而无需修改上下文类。

状态模式适用于以下场景:

  • 当一个对象的行为取决于其内部状态,并且需要在运行时切换状态时。
  • 当一个对象有多个状态,且状态之间需要相互转换和切换时。
  • 当需要消除大量的条件语句,使代码更加清晰和易于维护时。

状态切换与动态切换

状态模式允许状态切换的灵活性,这意味着在运行时可以动态地改变对象的状态。考虑以下情况:在电梯运行时,如果有人按下了开门按钮,电梯应该立即停下并切换到打开状态。这就是动态状态切换的典型应用。

让我们通过代码示例来演示动态状态切换:

public class DynamicStateChangeExample {public static void main(String[] args) {Context context = new Context();State openState = new OpenState();State closeState = new CloseState();State runState = new RunState();context.setState(closeState);context.open(); // 动态切换到打开状态context.setState(runState);context.open(); // 打开状态下按下开门按钮,切换到停止状态context.setState(openState);context.run(); // 停止状态下按下运行按钮,切换到运行状态}
}

状态模式的实际应用

状态模式在实际应用中非常有用。例如,在电子邮件客户端中,邮件的状态可以是已读、未读、已删除等。使用状态模式,可以轻松管理邮件的状态,并根据不同状态显示不同的界面和行为。

另一个实际应用是在交通信号灯控制系统中。信号灯可以有不同的状态,如红灯、绿灯和黄灯。通过使用状态模式,可以管理信号灯的状态并确保它们按照正确的顺序切换。

状态模式与其他模式的关系

状态模式与策略模式有一些相似之处,因为它们都涉及将行为封装成对象。但状态模式关注对象在不同状态下的行为,而策略模式关注算法的选择和替换。它们的关键区别在于目的和应用场景。

总结

状态模式是一种用于管理对象状态和行为的强大设计模式。它允许对象在内部状态发生变化时动态改变其行为,从而提高了代码的可维护性和可扩展性。状态模式的高级用法包括动态状态切换和实际应用,使其成为解决一系列状态相关问题的有力工具。

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

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

相关文章

数据挖掘实验(二)数据预处理【等深分箱与等宽分箱】

一、分箱平滑的原理 (1)分箱方法 在分箱前,一定要先排序数据,再将它们分到等深(等宽)的箱中。 常见的有两种分箱方法:等深分箱和等宽分箱。 等深分箱:按记录数进行分箱&#xff0…

Altium Designer实用系列(二)----PCB绘图小技巧

一、技巧总结 1.1 丝印大小 在导入PCB之后,元器件的丝印一般都是strock font,个人感觉比较大,也不美观,但是一个个修改成true type又比较麻烦。简便方法是使用相似查找全部修改:   此时会选中所有stroke 类型的丝印&#xff…

【Java】微服务——RabbitMQ消息队列(SpringAMQP实现五种消息模型)

目录 1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯 1.2.技术对比: 2.快速入门2.1.RabbitMQ消息模型2.4.1.publisher实现2.4.2.consumer实现 2.5.总结 3.SpringAMQP3.1.Basic Queue 简单队列模型3.1.1.消息发送3.1.2.消息接收3.1.3.测试 3.2.WorkQueue3.…

GB/T 7134-2008 浇筑型工业有机玻璃板材检测

非改性浇筑PMMA板材是指甲基丙烯酸甲酯均聚物板材,或者甲基丙烯酸甲酯与丙烯酸酯类或甲基丙烯酸酯类单体的共聚物板材,通过适当的引发剂本体聚合生产。 GB/T 7134-2008浇筑型工业有机玻璃板材测试项目: 测试项目 测试方法 拉伸强度 GB/T …

电脑技巧:推荐一款桌面增强工具AquaSnap(附下载)

下载:飞猫盘|文件加速传输工具|云盘|橘猫旗下新概念云平台,取件码:ZdRW 一、软件介绍 AquaSnap(界面增强软件)是一款功能强大的界面增强软件。这款软件支持屏幕边缘吸附与屏幕分屏即多显示器控制、摇晃窗口…

【golang】go 返回参数 以及go中 裸返

一、Go 返回参数命名 在Golang中,命名返回参数通常称为命名参数。 Golang允许在函数签名或定义中为函数的返回或结果参数指定名称。或者可以说这是函数定义中返回变量的显式命名。基本上,它解决了在return语句中提及变量名称的要求。 通过使用命名返回参…

Linux 守护进程

一 何为守护进程 守护进程( Daemon )也称为精灵进程,是运行在后台的一种特殊进程,它独立于控制终端并且周期性 地执行某种任务或等待处理某些事情的发生,主要表现为以下两个特点: 长期运行。守护进程是一…

视频号直播弹幕采集

系列文章目录 websocket逆向http拦截websocket拦截视频号直播弹幕采集 系列文章目录前言技术分析分析技术选择前提准备事件分析消息去重用户进房用户发言用户送礼用户点赞用户唯一id前言 很多小伙伴倒在了礼物事件,还有用户唯一标识下。 本篇文章将讲解视频号直播弹幕的获取的…

gitlab登录出现的Invalid login or password问题

前提 我是在一个项目里创建的gitlab账号,想在别的项目里登录或者官网登录发现怎么都登陆不上 原因 在GitLab中,有两种不同的账号类型:项目账号和个人账号(官网账号)。 项目账号:项目账号是在特定GitLab…

某果的一个小参数分析

分析链接:aHR0cHM6Ly9hcHBsZWlkLmFwcGxlLmNvbS9hY2NvdW50 分析目标:X-Apple-I-Fd-Client-Info 1.在浏览器搜索关键词,打下断点 我们再里面进行搜索,定位到这个位置,可以看到X-Apple-I-FD-Client-Info这个参数等于e,…

【C++设计模式之解释器模式:行为型】分析及示例

简介 解释器模式(Interpreter Pattern)是一种行为型设计模式,它提供了一种解决问题的方法,通过定义语言的文法规则,解释并执行特定的语言表达式。 解释器模式通过使用表达式和解释器,将文法规则中的句子逐…

python内置模块winreg,以及使用winreg模块获取所有当前windows电脑已安装应用的安装信息

winreg模块 进入系统注册表的方法多种多样,最常见的就是运行窗口输入命令“regedit”,即可进入注册表,而Python的winreg模块可以对注册表进行一系列操作 "winreg"中的各个常量 注册表地址(HKEY_ )常量 winreg.HKEY_CLASSES_ROOT #存储应用和shell的信息 winreg…

用 HTTP 提交数据,基本就这 5 种方式

网页开发中,向服务端提交数据是一个基本功能,工作中会大量用 xhr/fetch 的 api 或者 axios 这种封装了一层的库来做。 可能大家都写过很多 http/https 相关的代码,但是又没有梳理下它们有哪几种呢? 其实通过 http/https 向服务端…

VBox启动失败、Genymotion启动失败、Vagrant迁移

VBox启动失败、Genymotion启动失败、Vagrant迁移 2023.10.9 最新版本vbox7.0.10、Genymotion3.5.0 Vbox启动失败 1、查看日志 Error -610 in supR3HardenedMainInitRuntime! (enmWhat4) Failed to locate ‘vcruntime140.dll’ 日志信息查看方法->找到虚拟机所在位置->…

对于L1正则化和L2正则化的理解

在DL中,L1和L2正则化经常被使用到,因为大于1L的正则化都是凸优化的问题,是个简单问题,可以被解决。 首先说正则的意义: 一切可以缓解过拟合的方法,都可以被叫做正则化 我最开始理解正则化的时候就是看lh…

在 Azure 中开发云原生应用程序:工具和技巧

Azure 中的云原生开发工具 Azure 包含一系列用于云原生应用程序开发的内置工具和服务。这里介绍的服务和工具是很好的入门选择。 发展 Azure 包括两个用于开发和构建云原生应用程序的主要工具:Visual Studio (VS) 和Azure应用服务。 VS 是一个集成开发环境&#…

【Bond随你温故Azure Architecture】之HADR篇

上次复盘数据保护策略还是在《数据需要找回怎么办?我们如何选择正确的恢复/退回方式?》探讨了在application&DB层面上,不同level的数据保护有不同策略。而它也恰好是今天HA&DR版图的一角(RDBMS部分)&#xff0…

CI/CD工具中的CI和CD的含义

CI/CD工具中的CI和CD的含义? CI/CD 是现代软件开发方法中广泛使用的一种方法。其中,CI 代表持续集成(Continuous Integration),CD 则有两层含义,一是持续交付(Continuous Delivery)…

.net framework中webapi使用swagger进行接口文档展示

第一步:在nuget程序包管理中搜索“Swashbuckle”包,然后进行安装(注:如果是.net core api请安装Sawshbuckle aspnetcore)。 第二步:打开项目App_Start文件夹,修改SwaggerConfig.cs配置文件 我这…

mp4视频太大怎么压缩变小?

mp4视频太大怎么压缩变小?确实,很多培训和教学都转向了线上模式,这使得我们需要下载或分享大量的在线教学视频。然而,由于MP4视频文件通常较大,可能会遇到无法打开或发送的问题。为了解决这个问题,我们可以…