状态模式S

news2025/2/5 15:42:48

状态模式(State Pattern)是行为设计模式的一种,它允许一个对象在其内部状态发生改变时改变其行为。这个对象被视为类型的有限状态机(Finite State Machine)。

在状态模式中,我们创建表示各种状态的对象和一个上下文对象(context),该上下文对象持有当前状态的引用,并可以在不同状态之间切换。这些状态对象共享一个公共的接口,以便上下文可以与任何状态对象交互,而无需知道具体是哪个状态。这样,当状态发生改变时,上下文的行为也会相应改变,但上下文本身并不直接修改其状态,而是委托给状态对象来处理状态的转换。

组成

‌状态接口或抽象类‌(State)

定义一个接口或抽象类,以封装与特定状态相关的行为。

‌具体状态类‌(Concrete State)

实现或继承状态接口或抽象类,每个具体状态类实现与状态相关的行为,并可以定义状态转换的逻辑。

‌上下文类‌(Context)

持有一个状态对象的引用,可以委托当前状态对象处理请求,从而使得上下文的行为随状态改变而改变。上下文类通常包含一个或多个与状态相关的方法,这些方法会调用状态对象的方法。

Demo

设计一个交通信号灯系统。交通信号灯有三种状态:红灯(Red)、绿灯(Green)和黄灯(Yellow)。我使用状态模式来实现信号灯状态的切换和状态相关的行为。

定义状态接口 TrafficLightState

package org.example.state;

public interface TrafficLightState {
    void change(TrafficLight trafficLight);
}

状态接口具体的实现类 RedState,RedState,RedState

package org.example.state;

public class RedState implements TrafficLightState{
    @Override
    public void change(TrafficLight trafficLight) {
        System.out.println("Red Light -- Stop!");
        trafficLight.setState(new GreenState());
    }
}

package org.example.state;

public class GreenState implements TrafficLightState{
    @Override
    public void change(TrafficLight trafficLight) {
        System.out.println("Green Light -- Go!");
        trafficLight.setState(new YellowState());
    }
}

package org.example.state;

public class YellowState implements TrafficLightState{
    @Override
    public void change(TrafficLight trafficLight) {
        System.out.println("Yellow Light -- Gaution!");
        trafficLight.setState(new RedState());
    }
}

创建一个 TrafficLight 类作为上下文

package org.example.state;

public class TrafficLight {
    private TrafficLightState state;

    public TrafficLight() {
        this.state = new RedState();
    }

    public void setState(TrafficLightState state) {
        this.state = state;
    }

    public void change() {
        state.change(this);
    }
}

测试

package org.example.state;

public class StateMain {
    public static void main(String[] args) {
        TrafficLight light = new TrafficLight();
        for (int i = 0; i <= 10; i++) {
            light.change();
        }
    }
}

<font style="color:rgb(51, 51, 51);">LightState</font>接口定义了一个<font style="color:rgb(51, 51, 51);">pressButton</font>方法,该方法用于处理按下按钮时的行为。<font style="color:rgb(51, 51, 51);">OnState</font><font style="color:rgb(51, 51, 51);">OffState</font>类实现了这个接口,并分别定义了开状态和关状态下按下按钮的行为。<font style="color:rgb(51, 51, 51);">LightSwitch</font>类持有一个<font style="color:rgb(51, 51, 51);">LightState</font>对象的引用,并通过<font style="color:rgb(51, 51, 51);">pressButton</font>方法委托当前状态对象处理按下按钮的请求。在客户端代码中,我们创建了一个<font style="color:rgb(51, 51, 51);">LightSwitch</font>对象,并模拟了按下按钮的动作,可以看到电灯的状态在开和关之间切换

优点

  • ‌封装性良好‌:状态模式将状态相关的行为封装在独立的状态类中,使得状态的变化对上下文类来说是透明的。
  • ‌扩展性强‌:通过添加新的状态类,可以很容易地扩展系统的行为,而无需修改现有的代码。
  • ‌维护性高‌:状态模式使得状态转换和状态相关的行为明确且集中,有助于代码的维护和调试。
  • ‌解耦‌:状态模式将状态的行为与上下文类解耦,使得上下文类可以专注于处理业务逻辑,而无需关心状态的具体实现。

缺点

  • ‌类数量增加‌:每个状态都需要一个单独的类,这会导致系统的类数量增加,从而增加了管理的复杂性。
  • ‌逻辑分散‌:状态转换和状态相关的行为被分散到多个状态类中,这可能会使得理解和跟踪系统行为变得更加困难。
  • 适用场景

适用场景

对象的行为取决于其状态,并且这些状态在运行时会发生变化。需要使用大量的条件语句(如if-else或switch-case)来根据对象的状态选择其行为,这时可以考虑使用状态模式来替代这些条件语句,以提高代码的可读性和可维护性。

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

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

相关文章

数据结构 (23)并查集与等价类划分

一、并查集 并查集&#xff08;Union-Find Set或Disjoint Set&#xff09;是一种数据结构&#xff0c;用于处理一些不相交集合&#xff08;disjoint sets&#xff09;的合并及查询问题。它通常表示为森林&#xff0c;并用数组来实现&#xff08;类似于二叉堆&#xff09;。在并…

【Linux】开启你的Linux之旅:初学者指令指南

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01; 在 Linux 开发中&#xff0c;GDB 调试器和 Git 版本控制工具是开发者必备的利器。GDB 帮助快速定位代码问题&#xff0c;Git 则提供高效的版本管理与协作支持。本指南将简明介绍两者的核心功能与使用技巧&…

Python语法1

Python语法1 作者&#xff1a;王珂 邮箱&#xff1a;49186456qq.com 文章目录 Python语法1[TOC] 前言一、环境搭建1.1 安装Python解释器1.2 安装第三方包1.3 安装Pycharm1.4 虚拟环境 二、Python语法2.1 基础语法2.1.1 注释2.1.2 变量2.1.3 数据类型2.1.4 关键字和标识符 2.2…

普及组集训--图论最短路径

定义&#xff1a;表示顶点u到顶点v的一条边的权值&#xff08;边权&#xff09; 最短路径算法有常见的四种&#xff1a;floyd&#xff0c;dijkstra&#xff0c;Bellman-Ford&#xff0c;SPFA 不过Bellman-Ford并不常用&#xff0c;所以本文不提&#xff1b; 重点在于dijkstr…

蓝桥杯第 23 场 小白入门赛

一、前言 好久没打蓝桥杯官网上的比赛了&#xff0c;回来感受一下&#xff0c;这难度区分度还是挺大的 二、题目总览 三、具体题目 3.1 1. 三体时间【算法赛】 思路 额...签到题 我的代码 // Problem: 1. 三体时间【算法赛】 // Contest: Lanqiao - 第 23 场 小白入门赛 …

前缀和篇——繁星斗斗数字交织中,觅得效率明月辉光(1)

前言 在这片无边无际的数字海洋中&#xff0c;如何从中提取出有价值的讯息&#xff0c;成为了计算机科学中的一项重要课题。前缀和算法&#xff0c;作为一种巧妙的技术&#xff0c;恰如其名——通过计算序列中各个元素的前缀和&#xff0c;能够为我们提供一种高效的查询方式&a…

STM32 HAL库 + LM2904运算放大器 + ADC + VDO温度传感器:电路设计及代码实现

本文将详细介绍如何使用STM32F407的HAL库&#xff0c;实现通过单通道ADC采集VDO温度传感器的信号&#xff0c;并通过串口将采集到的温度值打印输出。具体流程包括&#xff1a;通过分压电阻将获得VDO温度传感器的分压电压&#xff0c;再利用运算放大器LM2904对信号进行放大&…

Python酷库之旅-第三方库Pandas(252)

目录 一、用法精讲 1191、pandas.tseries.offsets.BusinessMonthBegin.n属性 1191-1、语法 1191-2、参数 1191-3、功能 1191-4、返回值 1191-5、说明 1191-6、用法 1191-6-1、数据准备 1191-6-2、代码示例 1191-6-3、结果输出 1192、pandas.tseries.offsets.Busine…

【Linux服务器】CPU问题排查

概述 总体排查思路 总体观察&#xff0c;htop命令观察系统负载程度 检查CPU占用高的进程检查CPU硬件信息是否为问题根源从宏观到细节分析系统IO情况最后检查系统日志 排查思路 系统负载 通过htop命令查看系统负载&#xff0c;通过系统负载可以判断系统是否繁忙&#xff0c;主…

详解MyBatis之篇一

目录 MyBatis 定义 使用MyBatis操作数据库 创建项目 配置 演示 UserInfo.java UserInfoMapper UserInfoMapperTest 数据准备 自动生成测试类 运行结果 MyBatis 定义 MyBatis 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避…

编译器优化技术

方法内联 逃逸分析 公共子表达式消除 数据边界检查消除

汽车IVI中控开发入门及进阶(三十五):架构QML App Architecture Best Practices

在Qt/QML工程的架构中,架构很重要,虽然本身它有分层,比如QML调用资源文件(图片等)显示GUI界面,后面的CPP文件实现界面逻辑,但是这个分类还有点粗。在实际开发中,界面逻辑也就是基于类cpp的实现,也开始使用各种面向对象的设计模式,实现更加优秀的开发架构,这点尤其在…

本地Docker部署个人在线音乐平台Melody结合内网穿透远程访问听音乐

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

异常--C++

文章目录 一、异常的概念及使用1、异常的概念2、异常的抛出和捕获3、栈展开4、查找匹配的处理代码5、异常重新抛出6、异常安全问题7、异常规范 二、标准库的异常 一、异常的概念及使用 1、异常的概念 异常处理机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并…

字符串p型编码

字符串p型编码 C 语言实现C 实现Java 实现Python 实现 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 给定一个完全由数字字符&#xff08;‘0’,‘1’,‘2’,…,‘9’&#xff09;构成的字符串str&#xff0c;请写出str的p型编码串。例如&…

UIlicious - 自动化端到端测试

在现代软件开发中&#xff0c;测试自动化已然成为产品交付质量的基石。而端到端测试&#xff08;E2E&#xff09;&#xff0c;作为验证整个应用流畅运行的关键&#xff0c;常常是测试工作中最具挑战性的一环。这时&#xff0c;一款简单高效的自动化测试工具——UIlicious&#…

机器学习:机器学习项目的完整周期

建立一个有价值的机器学习系统时&#xff0c;需要考虑和计划哪些步骤&#xff1f; 以语音识别为例演示机器学习项目的全周期&#xff1a;机器学习项目的第一步是对项目进行范围划分&#xff0c;即决定什么是项目和你想做什么&#xff0c;然后是收集数据&#xff0c;所以决定需…

浪潮X86服务器NF5280、8480、5468、5270使用inter VROC Raid key给NVME磁盘做阵列

Inter VROC技术简介 Intel Virtual RAID on CPU (Intel VROC) 简单来说就是用CPU的PCIE通道给NVME硬盘做Raid 更多信息可以访问官方支持页面 Raid Key 授权&#xff0c;即VROC SKU 授权主要有用的有2个标准和高级&#xff0c;仅Raid1的授权我暂时没见过。 标准 VROCSTANMOD …

ROS基本框架2——在ROS开发中创建并使用自定义消息(C++版本)

ROS基本框架2——在ROS开发中创建并使用自定义消息(C++版本) code review! 参考笔记 1.ROS基本框架1——编写简单的发布者和订阅者(C++和Python版本) 2.ROS基本框架2——在ROS开发中创建并使用自定义消息(C++版本) 文章目录 ROS基本框架2——在ROS开发中创建并使用自定义…

鸿蒙征文|鸿蒙技术分享:使用到的开发框架和技术概览

目录 每日一句正能量前言正文1. 开发环境搭建关键技术&#xff1a;2. 用户界面开发关键技术&#xff1a;3. 应用逻辑开发关键技术&#xff1a;4. 应用测试关键技术&#xff1a;5. 应用签名和打包关键技术&#xff1a;6. 上架流程关键技术&#xff1a;7. 后续维护和更新关键技术…