设计模式-状态模式 Java

模式概述

状态模式是一种行为设计模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式通过将各种状态对应的行为分割到不同的状态子类中,使得对象可以根据当前状态表现出不同的行为,并且状态转换变得更加清晰和可维护。

简单代码示例

java 复制代码
// 抽象状态
interface FanState {
    void turnUp(FanContext context);
    void turnDown(FanContext context);
    void printState();
}

// 具体状态:关闭
class OffState implements FanState {
    @Override
    public void turnUp(FanContext context) {
        context.setState(new LowState());
        System.out.println("风扇从【关闭】转为【低档】");
    }
    
    @Override
    public void turnDown(FanContext context) {
        System.out.println("风扇已经关闭,无法再调低");
    }
    
    @Override
    public void printState() {
        System.out.println("当前状态:关闭");
    }
}

// 具体状态:低档
class LowState implements FanState {
    @Override
    public void turnUp(FanContext context) {
        context.setState(new HighState());
        System.out.println("风扇从【低档】转为【高档】");
    }
    
    @Override
    public void turnDown(FanContext context) {
        context.setState(new OffState());
        System.out.println("风扇从【低档】转为【关闭】");
    }
    
    @Override
    public void printState() {
        System.out.println("当前状态:低档");
    }
}

// 具体状态:高档
class HighState implements FanState {
    @Override
    public void turnUp(FanContext context) {
        System.out.println("风扇已经是最高档,无法再调高");
    }
    
    @Override
    public void turnDown(FanContext context) {
        context.setState(new LowState());
        System.out.println("风扇从【高档】转为【低档】");
    }
    
    @Override
    public void printState() {
        System.out.println("当前状态:高档");
    }
}

// 上下文
class FanContext {
    private FanState currentState;

    public FanContext() {
        this.currentState = new OffState(); // 初始状态
    }

    public void setState(FanState state) {
        this.currentState = state;
    }
    
    public FanState getState() {
        return currentState;
    }

    // 对外暴露的方法,相当于"事件"
    public void pressTurnUpButton() {
        currentState.turnUp(this);
    }
    
    public void pressTurnDownButton() {
        currentState.turnDown(this);
    }
    
    public void printStatus() {
        currentState.printState();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        FanContext fan = new FanContext();
        fan.printStatus(); // 初始状态
        
        fan.pressTurnUpButton(); // 从关闭调高到低档
        fan.printStatus();
        
        fan.pressTurnUpButton(); // 从低档调高到高档
        fan.printStatus();
        
        fan.pressTurnUpButton(); // 尝试从高档继续调高
        fan.printStatus(); // 状态不变
        
        fan.pressTurnDownButton(); // 从高档调低到低档
        fan.printStatus();
        
        fan.pressTurnDownButton(); // 从低档调低到关闭
        fan.printStatus();
        
        fan.pressTurnDownButton(); // 尝试从关闭继续调低
        fan.printStatus(); // 状态不变
    }
}

技术细节

1.模式组成

组件 职责说明
环境类 也称为上下文,定义客户端需要的接口。它维护一个State子类的实例,这个实例定义了对象的当前状态
抽象状态类 定义一个接口,用以封装Context对象的特定状态所对应的行为
环境类 每一个子类实现一个与Context的一个状态相关的行为。每一个具体状态类对应Context的一个具体状态

2.优缺点

优点:

清晰的结构:将与特定状态相关的行为局部化到一个状态子类中,将不同状态的行为分割开来,满足了单一职责原则。

除庞大的条件分支语句:避免了在上下文类中编写冗长复杂的条件状态判断语句。

缺点:

结构复杂:对开闭原则的支持并不完美。虽然增加新状态很容易,但修改状态转换逻辑(比如一个事件能触发哪些状态变化)可能需要修改多个状态类的代码。

和策略模式区别

虽说两种设计模式类图结构上几乎一模一样,但它们的意图和解决的问题完全不同。

  • 当需要灵活地切换多种算法来完成一个任务时,用策略模式。它是"主动"的,由客户端控制。
    类比:你要去旅行,可以选择不同的策略(交通工具):飞机、高铁、自驾。你根据成本、时间等因素主动选择其中一种,这些方式之间 没有必然联系,你也不会因为上了飞机就自动变成高铁。
  • 当有一个对象,其行为主要由内部状态决定,并且状态会随着其操作而改变时,用状态模式。它是"被动"的,状态转换对客户端是透明的。
    类比:电视遥控器有状态:开机状态、关机状态、静音状态。你按"电源"键,这个行为的结果取决于当前状态。在开机状态下按,会关机;在关机状态下按,会开机。状态的转换是由触发的事件(按按钮)和当前状态共同决定的,不是你显式地"选择"一个状态。

模式应用

Spring官方提供了一个名为Spring State Machine的子项目,它专门用于帮助开发者将状态机模式应用到Spring应用中

相关推荐
云雀衔光13 分钟前
Java Spring AI MCP:在 Spring 里把 AI 接上你的业务系统
java·开发语言·人工智能·后端·测试工具·spring
重生之小比特16 分钟前
【Java SE】数据类型与变量
java·开发语言·python
苏渡苇16 分钟前
Spring Insight 里如何对 Span 进行清洗
java·spring boot·后端·spring·系统监控
find1star17 分钟前
LeetCode 54:螺旋矩阵——用四个边界模拟矩阵收缩
java·算法·leetcode·边缘计算·学习方法
Yeniden19 分钟前
Java 后端从零到企业级:第1篇 Java 基础语法——变量、数据类型与运算符
java·开发语言·apache
邪修king20 分钟前
Linux系统篇(二十三) 基础 IO:从“文件”到“文件描述符”,彻底理解重定向
android·java·linux
云雀衔光29 分钟前
MCP + 应用生成:让 AI 直接产出可交互的应用
java·人工智能·测试工具·microsoft·交互·ai编程
Nuanyt44 分钟前
JVM常见核心知识梳理02 类加载 字节码技术 双亲委派 Java内存模型 JMM 并发底层 volatile synchronized 常见排障与调优工具
java·开发语言·jvm
Shan12051 小时前
经典算法题示例与详解:飞地的数量(二)
java·数据结构·算法
一嘴一个橘子1 小时前
java - redis 缓存雪崩
java