状态模式(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 || 变为 绿灯

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

相关推荐
氦客几秒前
Kotlin知识体系(二) : Kotlin的七个关键特性
android·开发语言·kotlin·安卓·特性·data class·密封类
努力学习的小廉4 分钟前
【红黑树】—— 我与C++的不解之缘(二十五)
开发语言·数据结构·c++
果冻kk7 分钟前
【宇宙回响】从Canvas到MySQL:飞机大战的全栈交响曲【附演示视频与源码】
java·前端·数据库·spring boot·mysql·音视频·html5
Achou.Wang23 分钟前
go语言中空结构体
开发语言·后端·golang
拓端研究室TRL24 分钟前
【视频】文本挖掘专题:Python、R用LSTM情感语义分析实例合集|上市银行年报、微博评论、红楼梦、汽车口碑数据采集词云可视化
开发语言·python·r语言·汽车·lstm
程序媛小盐28 分钟前
Java基础编程练习第34题-正则表达式
java·开发语言·正则表达式
炬火初现29 分钟前
Go语言的基础类型
开发语言·后端·golang
极客先躯31 分钟前
高级java每日一道面试题-2025年3月06日-微服务篇[Eureka篇]-Eureka服务注册与发现是什么?
java·微服务·eureka
少年的范儿33 分钟前
maven在windows系统上的详细安装和配置
java·windows·maven
不如打代码KK37 分钟前
jvm中每个类的Class对象是唯一的吗
java·jvm