状态模式(State Pattern)

状态模式(State Pattern)

定义

也称为状态机模式(State Machine Pattern)

通过定义不同的状态类来封装与特定状态相关的行为,并将状态的判断逻辑转移到表示不同状态的一系列类中,从而把复杂的判断逻辑简化。

  • 状态模式将状态和行为分开,使对象在内部状态改变时能够改变它的行为。
  • 每一个状态对应一个子类,从而将状态的转换逻辑分布到状态子类中,减少了相互依赖。
  • 客户端通常不直接与状态对象交互,而是通过环境类(Context)与状态对象进行交互。

适用场景

  1. 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
  2. 一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

标准示例

在状态模式结构图中,通常包含以下几个角色:

  • Context(环境类):也称为上下文类,它是拥有多种状态的对象。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态。
  • State(抽象状态类):用于定义一个接口以封装与环境类的一个特定状态相关的行为。在抽象状态类中声明了各种不同状态对应的方法,并在子类中实现这些方法。
  • ConcreteState(具体状态类):它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为。

IState

java 复制代码
public interface IState {
    void handle();
}

ConcreteStateA

java 复制代码
public class ConcreteStateB implements IState{
    public void handle() {
        System.out.println("状态B的动作");
    }
}

ConcreteStateB

java 复制代码
public class ConcreteStateB implements IState{
    public void handle() {
        System.out.println("状态B的动作");
    }
}

Context

java 复制代码
public class Context {
    public static final IState STATE_A = new ConcreteStateA();
    public static final IState STATE_B = new ConcreteStateB();

    private IState currentState = STATE_A;

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

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

客户端执行类

java 复制代码
public class ClientTest {
    public static void main(String[] args) {
        Context context = new Context();
        context.handle();

        context.setState(Context.STATE_B);
        context.handle();
    }
}

执行结果输出为:

java 复制代码
状态A的动作
状态B的动作

举个生活中常见的例子

交通信号灯有三种颜色,红、黄、绿。

它们会按照顺序切换。

我们使用状态模式,通过代码模拟一下三种信号灯的切换。
ITrafficState 抽象状态类
TrafficStateRed 红灯
TrafficStateYellow 黄灯
TrafficStateGreen 绿灯
TrafficContext 上下文类

java 复制代码
public interface ITrafficState {
    String getName();
    void lightChange(TrafficContext context);
}
java 复制代码
@Data
public class TrafficStateRed implements ITrafficState{
    private String name = "红灯";
    public void lightChange(TrafficContext context) {
        context.setCurrentState(TrafficContext.GREEN_LIGHT);
    }
}
java 复制代码
@Data
public class TrafficStateYellow implements ITrafficState{
    private String name = "黄灯";
    public void lightChange(TrafficContext context) {
        context.setCurrentState(TrafficContext.RED_LIGHT);
    }
}
java 复制代码
@Data
public class TrafficStateGreen implements ITrafficState{

    private String name ="绿灯";
    public void lightChange(TrafficContext context) {
        context.setCurrentState(TrafficContext.YELLOW_LIGHT);
    }
}
java 复制代码
public class TrafficContext {
    public static final ITrafficState RED_LIGHT = new TrafficStateRed();
    public static final ITrafficState GREEN_LIGHT = new TrafficStateGreen();
    public static final ITrafficState YELLOW_LIGHT = new TrafficStateYellow();

    private ITrafficState currentState =  GREEN_LIGHT;

    public void setCurrentState(ITrafficState currentState) {
        this.currentState = currentState;
    }

    public void changeLight(){
        System.out.print("当前是:" + this.currentState.getName());
        this.currentState.lightChange(this);
        System.out.println("  || lightChange || 变为 "+this.currentState.getName());
    }
}
java 复制代码
//客户端测试类
public class ClientTest {
    public static void main(String[] args) {
        TrafficContext context = new TrafficContext();
        //默认绿灯,变为黄灯
        context.changeLight();
        //黄灯 -> 红灯
        context.changeLight();
        //红灯 -> 绿灯
        context.changeLight();
    }
}

执行结果为:

shell 复制代码
当前是:绿灯  || lightChange || 变为 黄灯
当前是:黄灯  || lightChange || 变为 红灯
当前是:红灯  || lightChange || 变为 绿灯

以上就是状态模式的全部内容,感谢阅读。

相关推荐
韦禾水16 分钟前
记录一次项目部署到tomcat的异常
java·tomcat
曦月合一25 分钟前
树莓派安装jdk、tomcat、vnc、谷歌浏览器开机自启等环境配置
java·tomcat·树莓派
harder32139 分钟前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
jinanwuhuaguo1 小时前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw
Rust研习社1 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust
此剑之势丶愈斩愈烈1 小时前
openssl 自建证书
java
面汤放盐1 小时前
何时使用以及何时不应使用微服务:没有银弹
java·运维·云计算
0xDevNull1 小时前
Spring Boot 自动装配:从原理到实践
java·spring boot·后端
qq_589568102 小时前
java学习笔记,包括idea快捷键
java·ide·intellij-idea
淘矿人3 小时前
从0到1:用Claude启动你的第一个项目
开发语言·人工智能·git·python·github·php·pygame