• 设计模式之状态模式


    阅读建议

    嗨,伙计!刷到这篇文章咱们就是有缘人,在阅读这篇文章前我有一些建议:

    1. 本篇文章大概2000多字,阅读时间长可能需要2-3分钟;
    2. 设计模式属于程序的设计思想、方法类的内容,阅读一遍,在理解上不一定会很透彻,建议收藏起来,有空多看看,书读百遍,其义自现;
    3. 创作不易,免费的点赞、关注,请走上一走,也算是对博主一些鼓励,可以让我更有动力输出更多的干货内容;

    什么是状态模式

            状态模式是一种行为型设计模式,允许对象在内部状态发生改变时改变它的行为。它适用于行为随状态改变而改变的场景,如一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态。状态模式的核心是状态与行为绑定,不同的状态对应不同的行为。它定义了各种状态类,每个状态类中定义了对应的状态行为,并且状态类之间通过继承实现状态的转移。通过使用状态模式,可以将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足单一职责原则。

    状态模式有哪些核心角色

    状态模式的核心角色包括:

    1. 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
    2. 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
    3. 具体状态(Concrete State)角色:实现抽象状态所对应的行为。

    状态模式如何实现

    需求描述

            状态模式很简单,也很容易理解,这里我举一个生活中的小例子来说明一下:比如我,平时一般都是7点钟起床开始洗漱,8点钟开车出门,9点钟到达公司,开始进入作状态,这就是简单朴实的一天。类似这种不同的状态或时刻,会触发一些固定的动作,并且动作之间具有一定的连贯性,使用状态模式就是一个比较好的选择。如果使用状态模式来模拟一下起床去上班这个过程,应该怎么实现呢?

    实现方法

    1、TaskState.java:声明抽象的任务状态,即抽象状态角色,封装了特定时刻下的行为;

    1. /**
    2. * 任务状态抽象
    3. */
    4. public abstract class TaskState {
    5. /**
    6. * 任务在某个状态时,做一些事
    7. */
    8. public abstract void doSomething(TaskContext taskContext);
    9. }

    2、TaskContext.java:任务的上下文环境,持有一个任务状态,并定义了当前任务状态一下具体动作;

    1. /**
    2. * 任务管理上下文
    3. */
    4. public class TaskContext {
    5. private TaskState taskState;
    6. public TaskState getTaskState() {
    7. return taskState;
    8. }
    9. public void setTaskState(TaskState taskState) {
    10. this.taskState = taskState;
    11. }
    12. public void handle(){
    13. this.taskState.doSomething(this);
    14. }
    15. }

    3、SevenState.java、EightState.java、NineState.java:继承于抽象的任务状态,是具体状态,分别实现了7点钟、8点钟、9点钟时的特定动作;

    1. /**
    2. * 7点钟的任务
    3. */
    4. public class SevenState extends TaskState{
    5. @Override
    6. public void doSomething(TaskContext taskContext) {
    7. System.out.println("7:00>起床洗漱");
    8. taskContext.setTaskState(new EightState());
    9. }
    10. }
    1. /**
    2. * 8点状的任务
    3. */
    4. public class EightState extends TaskState{
    5. @Override
    6. public void doSomething(TaskContext taskContext) {
    7. System.out.println("8:00>开车出门去上班");
    8. taskContext.setTaskState(new NineState());
    9. }
    10. }
    1. /**
    2. * 9点钟的任务
    3. */
    4. public class NineState extends TaskState{
    5. @Override
    6. public void doSomething(TaskContext taskContext) {
    7. System.out.println("9:00>到达公司,开始工作");
    8. }
    9. }

    4、Client.java:编写业务客户端把各任务状态整合到上下文环境中;

    1. public class Client {
    2. public static void main(String[] args) {
    3. SevenState sevenState = new SevenState();
    4. TaskContext taskContext = new TaskContext();
    5. taskContext.setTaskState(sevenState);
    6. taskContext.handle();
    7. taskContext.handle();
    8. taskContext.handle();
    9. }
    10. }

    状态模式适用哪些场景

            状态模式适用于处理一个对象在其内部状态改变时,其行为也随之改变的场景。具体来说,状态模式适用于以下特征的业务场景:

    1. 一个对象存在多个状态,这些状态可以相互转换。
    2. 不同状态下,对象的行为不同。
    3. 状态转换过程比较复杂,将状态判断逻辑转移到代表不同状态的一系列类中可以简化代码。

            例如,在视频播放的业务场景中,播放器有初始状态、播放状态、暂停状态、停止状态、快进状态等多种状态,将这些状态都封装到代表不同状态的类中,可以将复杂的判断逻辑简化,将这些逻辑扩展到不同的状态类中。

            此外,状态模式还适用于电梯运行、购买物品等场景。在电梯运行场景中,电梯的运行状态包括停止、上行、下行等,不同状态下行为不同。在购买物品场景中,可以将购物车中的商品订单状态封装到代表不同状态的类中,如未付款、已付款、已取消等状态,简化判断逻辑并提高代码可读性和可维护性。

    状态模式的优点和缺点

    优点

    1. 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
    2. 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
    3. 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

    缺点

    1. 状态模式的使用必然会增加系统的类与对象的个数。
    2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

    总结

            在实现上,状态模式增加了系统的类与对象的个数,并且状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。因此,在使用状态模式时需要注意其适用场景和优缺点,并根据实际情况进行权衡和选择。

  • 相关阅读:
    java EE初阶 — synchronized 关键字 - 监视器锁 monitor lock
    ES的常用查询
    计算机网络第一章笔记
    vuejs之父子组件的通信【props】和【$emit】
    hive排序
    【信管1.5】计算机网络基础(三)网络存储与网络接入
    Nature:“我还有用!“凋亡细胞释放的代谢物充当组织信使
    基于移动互联网的订餐APP系统设计与实现
    电脑报2022年第24期Scratch制作通讯录管理系统存在的小瑕疵
    【回归预测】基于正余弦算法优化神经网络实现数据回归预测附matlab代码
  • 原文地址:https://blog.csdn.net/fox9916/article/details/134284031