设计模式之状态模式

设计模式之状态模式_第1张图片

阅读建议

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

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

什么是状态模式

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

状态模式有哪些核心角色

设计模式之状态模式_第2张图片

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

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

状态模式如何实现

需求描述

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

实现方法

设计模式之状态模式_第3张图片

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

/**
 * 任务状态抽象
 */
public abstract class TaskState {

    /**
     * 任务在某个状态时,做一些事
     */
    public abstract void doSomething(TaskContext taskContext);
}

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

/**
 * 任务管理上下文
 */
public class TaskContext {
    private TaskState taskState;

    public TaskState getTaskState() {
        return taskState;
    }

    public void setTaskState(TaskState taskState) {
        this.taskState = taskState;
    }

    public void handle(){
        this.taskState.doSomething(this);
    }
}

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

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

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

public class Client {
    public static void main(String[] args) {
        SevenState sevenState = new SevenState();
        TaskContext taskContext = new TaskContext();
        taskContext.setTaskState(sevenState);
        taskContext.handle();
        taskContext.handle();
        taskContext.handle();
    }
}

状态模式适用哪些场景

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

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

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

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

状态模式的优点和缺点

优点

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

缺点

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

总结

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

你可能感兴趣的:(设计模式,设计模式,状态模式,java)