小侃设计模式(廿一)-状态模式

news2025/1/15 13:01:07

1.概述

状态模式(State Pattern)是行为型设计模式的一种,它主要用来解决对象存在多种状态转换时,需要对外输出不同的行为。状态模式与策略模式有一定相似,区别在于策略模式行为彼此独立,可以进行相互替换;状态模式将对象状态封装在不同对象中,不同状态显示不同行为,不同状态之间可能有触发条件和先后关系。状态模式相较于策略模式而言,客户端不需要关心当前对象的状态,而策略模式需要在客户端根据状态选择调用策略类。本文将详述状态模式的原理及使用。

2.原理及使用

2.1 原理

状态模式的UML类图如下所示:
在这里插入图片描述
类图中主要包含三个元素:抽象状态角色(State)、具体状态角色(ConcreteState)、环境类角色(Context)。具体解释如下:

抽象状态角色(State):定义一个接口,封装环境对象中的特定状态所对应的行为,接口中可以有一个或多个行为;
具体状态角色(ConcreteState):是State的实现,定义了具体的行为,在不同的场景下进行状态切换;
环境类角色(Context):定义了一个接口,内部维护一个当前状态,根据不同的状态进行具体状态角色切换,产生不同行为。

2.2 案例

有一个MP3播放器,有开始、停止、下一首、上一首等功能,这里主要以开始和结束状态为准。
根据状态模式,画出UML类图如下:
在这里插入图片描述
编码如下:

public interface State {

    void print();

    void handle(Context context);

}

public class StartState implements State {

    @Override
    public void print() {
        System.out.println("Start ......");
    }

    @Override
    public void handle(Context context) {
        System.out.println("开始播放。。。");
        context.setState(this);
    }
}

public class StopState implements State {

    @Override
    public void print() {
        System.out.println("STOP ......");
    }

    @Override
    public void handle(Context context) {
        System.out.println("停止播放。。。");
        context.setState(this);
    }
}


public class Context {

    private State state;

    public State getState() {
        return state;
    }

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

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

public class Client {

    public static void main(String[] args) {
        Context context = new Context();

        State startState = new StartState();
        startState.handle(context);
        System.out.print("当前状态:");
        context.getState().print();

        State stopState = new StopState();
        stopState.handle(context);
        System.out.print("当前状态:");
        context.getState().print();

    }
}

运行结果为:
在这里插入图片描述

2.3 优点和缺点

2.3.1 优点

1.代码有很强的可读性: 状态模式将每个状态的行为封装到对应的一个类中,使代码可读性更高;
2.方便维护: 避免大量的if…else语句,使代码更清晰一些;
3.符合开闭原则: 容易增加和删除状态。

2.3.1 缺点

1.容易造成类爆炸:当事件状态较多时,实现类会剧增;
2.容易造成代码混乱:当事件状态较多时,容易造成代码混乱;

3.小结

1.状态模式适用于行为随着状态而改变的场景,或者替换代码中存在的大量if…else语句;
2.状态模式能在一定程度上增加代码可读性。

4.参考文献

1.《设计模式之禅》-秦小波著
2.《大话设计模式》-程杰著
3.https://www.bilibili.com/video/BV1G4411c7N4-尚硅谷设计模式
4.https://www.runoob.com/design-pattern/observer-pattern.html

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

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

相关文章

VueJs中的toRef与toRefs函数的一个比较

前言ref是处理基本数据类型响应式API函数,在setup中声明定义的变量,可以直接在模板中使用没有被响应式API包裹处理的变量数据,是不具备响应式能力的也就是往往在逻辑中修改了数据,但是页面不会更新,那怎么样将一个非响应式数据变成响应式数据就需要用到toRef()与toRefs()这两个…

【计算机网络】网络编程套接字

文章目录理解源IP地址和目的IP地址理解端口号和进程ID理解源端口号和目的端口号认识TCP协议认识UDP协议网络字节序socket编程接口socket网址查看socket常见APIUDP协议实现网络通信UDP创建socket文件描述符sockaddr结构UDP绑定端口号UDP接收发送网络数据简单的UDP网络程序TCP协议…

拉伯证券|大股东或易主,阿里巴巴换股入局

三大股指齐上扬,早盘主力埋伏这些股。 到午间收盘,“家居零售榜首股”之称的美凯龙一字涨停,港股红星美凯龙涨24%,此前一度涨超30%。 消息面上,1月13日晚间,美凯龙发布公告称,公司控股股东红星…

transformer算法解析

本文参考: 详解Transformer (Attention Is All You Need) - 知乎 Transformer 代码完全解读!_AI科技大本营的博客-CSDN博客 Transformer学习笔记一:Positional Encoding(位置编码) - 知乎 1、…

【C语言】自定义类型

前言男孩子在外面要保护好自己~一、结构体为什么会有结构体呢&#xff1f;但要描述一个复杂对象时&#xff0c;仅用之前学过的基本数据类型表达不了&#xff08;如&#xff1a;我要描述一个人&#xff0c;仅靠基本数据类型只能说定义他的一种属性<如用 int 定义他的年龄>…

字符串的处理

一、字符数组 用来存放字符型数据的数组称为字符数组&#xff0c;其元素是一个个的字符。 char 字符数组名[常量表达式]&#xff1b; C语言规定字符串是以\0字符作为结束符的字符数组。 在程序中可以通过判断数组元素是否为空字符来判断字符串是否结束。 字符串的输…

介绍Java中的常/变量.各种数据类型以及类型转换和提升的用法

本文简单描述了什么是常量和变量,介绍了Java各种数据类型:基本数据类型(四类八种,大小和范围)和引用数据类型(种类),简单介绍了包装类字符串类型,以及不同数据类型之间的常量和变量,数据类型之间的转换和提升… Java常/变量和数据类型一.什么是常量?二.什么是变量?三.数据类型…

[审核]因为审核人员不了解苹果登录被拒

1.审核被拒信息 Guideline 2.1 - Information Needed We’re looking forward to completing the review of your app, but we need more information to continue. Next Steps Please provide detailed answers to the following questions in your reply to this message i…

寒假集训一期总结(一)–––思维训练

目录 思维训练 走方格 解题思路 参考代码 最短曼哈顿距离 ​编辑 解题思路 参考代码 酒厂选址 解题思路 参考代码 雪地足迹Tracks in the Snow 解题思路 参考代码 一个星期没有更博客了…这一个星期,去学校信竞集训的我收获颇丰,下面就是我的还加集训总结 思…

【小白向】让电脑成为热点WIFI

让电脑成为热点WIFI 本文针对下述情况&#xff0c;有一台电脑&#xff0c;一部手机&#xff0c;但是电脑通过网线连接。此时电脑可以上网&#xff0c;手机没有流量&#xff0c; 仅能通过WIFI上网&#xff0c;但此时没有WIFI。 其实你的电脑可能自己本身就能作为热点发布WIFI&…

绕任一向量旋转矩阵计算思考与实现

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 问题提出 如图所示&#xff0c;在空间中有一向量A&#xff0c;问点O绕A方向逆时针旋转角度α的矩阵如何表示。 问题分析 问题化规 直接去构造一个矩阵是比较困难的。…

自从我学会了Jenkins的自动构建,我再也没有每次都打包上传到服务器然后发布Java服务了

上次我们讲了使用Jenkins部署maven项目 工作两年半&#xff0c;终于学会了Jenkins部署Maven项目 这次我们来讲一下每次提交代码的时候Jenkins自动构建 我们使用的代码仓库是gitee 文章目录&#x1f3c3;第一步&#xff0c;我们在Jenkins中安装gitee插件&#x1f3c3;第二步&am…

Go语言并发编程及依赖管理

目录&#x1f9e1;并发编程GoroutineCSP(Communicating Sequential Processes)&#x1f9e1;依赖管理依赖演变依赖管理三要素&#x1f49f;这里是CS大白话专场&#xff0c;让枯燥的学习变得有趣&#xff01; &#x1f49f;没有对象不要怕&#xff0c;我们new一个出来&#xff0…

Linux (open、write、read、close、lseek、chmod、sync)操作文件的函数详解

目录 一、文件操作方式 二、Linux底层文件操作 1. open 2. write 3. read 4. close 5. lseek 6. chmod 7. sync、syncfs、fsync、fdatasync 三、 Linux 系统调用 四、总结 linux中&#xff0c;一切皆文件&#xff08;网络设备除外&#xff09; 硬件设备也“是”文件&a…

力扣刷题记录——507.完美数、509. 斐波那契数、520. 检测大写字母

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《507.完美数、509. 斐波那契数、520. 检测大写字母》。 目…

InfluxDB + Grafana计算成功率

文章目录方式一 借助Grafana的Transfrom方式二 Influx子查询Transfrom介绍建议针对每类Metric&#xff0c;使用一个Metric&#xff0c;增加success的tag区分成功还是失败。 方式一 借助Grafana的Transfrom 第一步&#xff1a;新建2个Query Query Total: SELECT sum("coun…

安科瑞电气火灾监控系统在春晓161#地块人防工程的设计与应用

安科瑞 华楠摘要&#xff1a;本文简述了电气火灾监控系统的组成原理&#xff0c;分析了电气火灾监控系统在应用中的设计依据和相关规范。通过安科瑞剩余电流式电气火灾监控系统在春晓161#地块人防工程电气火灾监控系统项目的实例介绍&#xff0c;阐述了电气火灾监控系统功能的实…

c语言实现扫雷(详细讲解)

本篇介绍,讲解如何使用c语言实现扫雷小游戏. 金句分享: ✨✨✨爱你所爱,行你所行✨✨✨ 目录前言:一、游戏设计思路介绍:效果展示二、游戏的分步讲解2.1、主函数测试区&#xff08;test.c&#xff09;基本构成2.2、游戏中函数实现区(game.c) (重点)2.21、雷盘的创建与初始化函…

centos8 Ambari-2.7.6.3+HDP-3.3.1离线安装详细教程(附安装包)

自2021年1月31日开始,所有Cloudera软件都需要有效的订阅,且订阅费昂贵。此外,CDH6和HDP3将是CDH和HDP的最后企业版本,原有企业版用户无法继续获取新的功能和性能提升。至2022年3月份,CDH/HDP全部停止服务(EoS),用户没办法获取售后支持。由于生产环境系统升级到centos8,…

linux 中 PCIE 中断映射机制

PCIE 中断映射机制 1、 PCIE 中有三种中断方式&#xff0c; MSI&#xff0c;MSI-X 和INTx PCIe总线继承了PCI总线的所有中断特性&#xff08;包括INTx和MSI/MSI-X&#xff09;&#xff0c;以兼容早期的一些PCI应用层软件。 PCI总线最早采用的中断机制是INTx&#xff0c;这是…