设计模式第10式:状态模式

article/2025/9/22 10:43:56

前言

我们遇到状态机模型,常常会理不清“状态”和“行为”的关系。状态模式就是专门解决这个应用场景的,它通过改变对象内部的状态来帮助对象控制自己的行为。

正文

1、先来看一个案例

我们选取《HeadFirst 设计模式》中的糖果售卖机案例。这就是常见的状态机模型。
在这里插入图片描述
首先我们找出所有的状态:上图中的4个圆圈。于是我们用4个常量来表示每个状态:

final static int SOLD_OUT = 0;
final static int NO_QUARTER = 1;
final static int HAS_QUARTER = 2;
final static int SOLD = 3;int state = SOLD_OUT; // 初始状态

然后我们将系统中可以发生的动作整理出来,每个动作都对应一个方法。下面这个方法就是投币动作对应的方法。方法里面对每一个可能出现的状态展示适当的行为。

public void insertQuarter() {if (state == HAS_QUARTER) {sout("不能再投币了");} else if (state == SOLD_OUT) {sout("卖完了");} else if (state == SOLD) {sout("已售出");} else if (state == NO_QUARTER) {state = HAS_QUARTER;sout("已投币");}
}public void ejectQuarter() {if (state == HAS_QUARTER) {...} else if (state == SOLD_OUT) {...} else if (state == SOLD) {...} else if (state == NO_QUARTER) {...}
}public void turnCrank() {if (state == HAS_QUARTER) {...} else if (state == SOLD_OUT) {...} else if (state == SOLD) {...} else if (state == NO_QUARTER) {...}
}public void dispense() {if (state == HAS_QUARTER) {...} else if (state == SOLD_OUT) {...} else if (state == SOLD) {...} else if (state == NO_QUARTER) {...}
}

其他的动作方法类似,里面都有一大堆if else代码。当我们费尽九牛二虎之力写完后,要加入新的需求:当转动糖果机摇杆,有10%的几率掉下来2颗糖果。这种情况下完全失控了,每一个动作方法都要跟着修改,改出BUG的几率会大大增加。

2、如何优化

仍然遵循“封装变化”的原则,我们将每个状态的行为都放在各自的类中,那么每个状态只需要实现它自己的动作就可以了。这样,糖果机只需要将动作委托给当前的状态对象。

  • 首先,我们定义一个State接口,在这个接口中,糖果机的每个动作都有一个对应的方法;
  • 然后,为机器中的每个状态实现一个状态类,这些类将负责在对应状态下进行机器的行为;
  • 最后,我们将糖果机的动作委托给状态类。

在这里插入图片描述
我们尝试实现其中一个状态类,我们要做的是实现当前状态下恰当的行为:

public class NoQuarterState implements State {Machine machine;// 构造器拿到糖果机的引用public NoQuarterState(Machine machine) {this.machine = machine;}// 当前状态下触发动作的结果public void insertQuarter() {sout("已投币");// 触发糖果机改变状态machine.setState(machine.getHasQuarterState());}public void ejectQuarter() {sout("未投币");}public void turnCrank() {sout("未投币");}public void dispense() {sout("未投币");}
}

于是我们重新改造糖果机:

public class Machine {// 常量替换成4个状态类State soldOutState;State noQuarterState;State hasQuarterState;State soldState;State state = soldOutState; // 当前状态// 构造方法初始化每种状态public Machine() {soldOutState = new SoldOutState(this);noQuarterState= new NoQuarterState(this);hasQuarterState= new HasQuarterState(this);soldState = new SoldState(this);}// 糖果机的动作均委托给当前状态类的动作方法public void insertQuarter() {soldState.insertQuarter();}public void ejectQuarter() {soldState.ejectQuarter();}public void turnCrank() {soldState.turnCrank();}public void dispense() {soldState.dispense();}
}

3、定义状态模式

上面已经实现了状态模式,我们来对其进行一个定义:

状态模式允许对象在内部状态改变时改变它自身的行为,对象看起来好像修改了它的类。
  • 这个模式将状态封装成独立的类,并将动作委托给当前状态对象
  • 从用户的视角来看,如果使用的对象能否完全改变自己的行为,那么这个对象应该是从别的类实例化而来的。然而,状态模式仅通过组合不同的状态对象来造成改变类行为的假象。

我们来定义下状态模式的类图:
在这里插入图片描述

4、状态模式 vs 策略模式

两个模式的类图很相似,但是两个模式的行为不一样:策略模式替换算法是由用户自己控制的,状态模式替换算法是系统内部自行控制的。

总结

状态模式针对状态机场景有很好的模型总结,我们遇到状态机模型,都要首先考虑状态模式。


http://chatgpt.dhexx.cn/article/pknoAZC4.shtml

相关文章

# 设计模式

设计模式 文章目录 设计模式设计模式总览单例模式类图定义特点单例模式的实现方式 工厂模式类图定义特点实现方式 抽象工厂模式类图定义特点实现方式 观察者模式类图简单理解使用场景实例代码 策略模式类图简单理解使用场景实例代码 模板方法模式类图简单理解实例代码 原型模式…

安全漏洞与网络攻击

目录 一、安全漏洞及产生原因 1. 安全漏洞概念 2. 漏洞产生的技术原因 3. 漏洞产生的经济原因 二、信息收集与分析 1. 攻击的过程 2. 信息收集:攻击的前奏 3. 收集什么信息 4. 信息收集与分析工具 5. 公开信息收集-搜索引擎 6. 信息收集与分析 7. 信息收…

网络安全学习-WEB安全常见漏洞

注入类漏洞 SQL注入漏洞 定义 sql注入漏洞,就是将用户可控的数据拼接到了sql语句当中,一起提交到了数据库执行。 攻*击者通过注入语句,改变sql执行的逻辑,通过控制部分sql语句,攻击者可以查询到数据库钟任何自己需要…

网站安全漏洞--大全

原文网址:网站安全漏洞--大全_IT利刃出鞘的博客-CSDN博客 简介 本文介绍网站常见的一些安全漏洞。 常见的漏洞有:SQL 注入、越权操作、跨站脚本攻击(XSS)、跨站请求伪造(CSRF)、DDoS 攻击、JSON 劫持、暴力破解、HTTP 报头追踪漏洞、信息泄露、文件上…

Springboot -- 网络安全漏洞处理

文章目录 不安全的 HTTP 方法以及 Nginx 屏蔽版本号显示说明检测方式不安全的 HTTP 方法 处理代码屏蔽 Nginx 版本号显示 点击劫持漏洞说明什么是ClickJacking检测方式处理代码 XSS跨站脚本攻击说明检测方式处理代码 (参考网上的代码,主要是对传入的信息…

网络安全实验3 漏洞扫描

赞赏码 & 联系方式 & 个人闲话 【实验名称】漏洞扫描 【实验目的】 1.熟悉X-Scan工具的使用方法; 2.熟悉FTPScan工具的使用方法; 3.会使用工具查找主机漏洞 4.学会对弱口令的利用 5.了解开启主机默认共享以及在命令提示下开启服务的方法 …

网络安全技能大赛D模块常规漏洞加固详解

一、 说明: 1.所有截图要求截图界面、 字体清晰; 2.文件名命名及保存: 网络安全模块 D- XX(XX为工位号), PDF 格式保存; 3.文件保存到 U盘提交。 4.linux 系统 root 密码 123456; 请…

2022年统计的27个网络安全漏洞数据信息

网络安全漏洞通常是指软件代码中允许攻击者访问网络或系统的缺陷。漏洞使企业和个人面临一系列威胁,包括恶意软件和帐户接管。 他们的漏洞利用存在大量可能的漏洞和潜在后果。美国政府的国家漏洞数据库 (NVD)由常见漏洞和暴露 (CVE) 列表提供,目前有超过…

计算机漏洞分几个等级,网络安全漏洞可以分为各个等级,A级漏洞表示?

满意答案 某匪kevin 2013.04.04 采纳率:44% 等级:11 已帮助:5835人 答案时B ----------------分级原则----------- 对漏洞分级有助于在漏洞被发现后,提供用户更多的信息以便于更快的给漏洞定位,并决定下一步采取的措…

网络安全常见漏洞原理及其防御

目录 1.SQL注入 1.1原理 1.2注入演示 1.3防御 1.4 补充 2.xss(跨站脚本攻击) 2.1 原理 2.2 注入演示 2.3防御 3.csrf(跨站点请求伪造) 3.1原理 3.2 注入演示 3.3 防御 4.文件上传 4.1原理 4.2 攻击演示 4.3防御 1.…

医疗器械网络安全漏洞自评报告模板

提示:编制医疗器械网络安全漏洞自评报告要点解析 文章目录 1. 目的2. 引用文件3. CVSS漏洞等级3.1 概述3.1.1 适用范围说明3.1.2 CNNVD-ID定义3.1.3 编码原则3.1.4 CNNVD-ID语法介绍 3.2 指标分析3.2.1 基本指标3.2.1.1可用性指标1)攻击向量2)攻击复杂性3)所需权限4…

Web网络安全漏洞分析,SQL注入原理详解

本文主要为大家介绍了Web网络安全漏洞分析SQL注入的原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪 一、SQL注入的基础 1.1 介绍SQL注入 SQL注入就是指Web应用程序对用户输入数据的合法性没…

信息安全技术 网络安全漏洞分类分级指南(GB/T 30279-2020 )

文章目录 前  言1 范围2 规范性引用文件3 术语和定义4 缩略语5 网络安全漏洞分类5.1 概述5.2 代码问题5.3 配置错误5.4 环境问题5.5 其他 6 网络安全漏洞分级6.1 概述6.2 网络安全漏洞分级指标6.3 网络安全漏洞分级方法 附 录 A(规范性附录&#…

计算机网络存在的漏洞,常见的计算机网络安全漏洞有哪些

当今的世界呈现网络信息化、网络全球化的发展大趋势。因此,我们应该竭尽全能地享受其带来的优势和便利,让信息网络为人类的生活进行健康服务。同时,我们还应该采取一切措施将各类危害网络信息安全的病毒清扫干净。只有防患于未然,…

信安软考 第十三章 网络安全漏洞防护技术原理

一、网络安全漏洞概述 1.1 网络安全漏洞概念 网络安全漏洞又称为脆弱性,简称漏洞。漏洞一般是致使网络信息系统安全策略相冲突的缺陷,这种缺陷通常被称为安全隐患。安全漏洞的影响主要有机密性受损、完整性破坏、可用性降低、抗抵赖性缺失、可控性下降、…

网络安全漏洞检测

漏洞检测 任务说明:仅能获取Server3的IP地址 靶机场景:Server3 172.16.101.250 在MSF工具中用search命令搜索MS12020 RDP拒绝服务攻击模块,将回显结果中的漏洞披露时间作为Flag值提交;(如:2012-10-16&am…

网络安全常见十大漏洞总结(原理、危害、防御)

一、弱口令【文末福利】 产生原因 与个人习惯和安全意识相关,为了避免忘记密码,使用一个非常容易记住 的密码,或者是直接采用系统的默认密码等。 危害 通过弱口令,攻击者可以进入后台修改资料,进入金融系统盗取钱财…

网络安全常见十大漏洞总结(原理、危害、防御)_网络安全十大漏洞

一、弱口令【文末福利】 产生原因 与个人习惯和安全意识相关,为了避免忘记密码,使用一个非常容易记住 的密码,或者是直接采用系统的默认密码等。 危害 通过弱口令,攻击者可以进入后台修改资料,进入金融系统盗取钱财…

【python】采集每日必看黄色软件数据~

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 环境使用: Python 3.8 Pycharm 模块使用: requests >>> pip install requests re csv 安装模块:win R 输入cmd 输入安装命令 pip install 模块名 如果出现爆红 可能是因为 网络连接超时 切换国内…

HTML5游戏化互动学习平台,h5游戏平台_触摸型互动slg黄油手游

乐趣H5游戏平台是目前中国最大的H5手机网页游戏平台,提供在线玩的H5手机小游戏,最火爆的微信小游戏,最好玩的手机小游戏排行榜,让您能结识到H5游戏玩家和H5小游戏里的朋友,无需下载,点击马上玩!…