23种设计模式中的状态模式

状态模式是一种行为型设计模式,它允许对象在内部状态改变时改变它的行为,看起来好像改变的是这个对象的类。

状态模式经常用在带有状态的对象中。

什么是状态?假设一个对象,有如下三种状态:

  • 开始状态
  • 运行状态
  • 结束状态

定义一个枚举类,表示不同的状态,但是不同的状态需要表现不同的行为,如下:

scss 复制代码
if(state == START){
    // 执行开始状态下逻辑
}else if(state == RUNNABLE){
    // 执行运行状态下逻辑
}else if(state == STOP){
    // 执行结束状态下逻辑
}

状态模式设计的目的是为了把上述一大堆 if else 代码拆分为不同的状态,然后封装成不同的状态类,使得将来增加状态比较容易。

接下来,使用状态模式优化上述代码。

定义状态接口:

csharp 复制代码
// 定义状态接口
interface State {
    void doAction(Context context);
}

对于开始状态,设计如下:

typescript 复制代码
// 开始状态类
class StartState implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("Start State");
        context.setState(new RunState());
    }
}

对于运行状态,设计如下:

typescript 复制代码
// 运行状态类
class RunState implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("Run State");
        context.setState(new StopState());
    }
}

对于停止状态,设计如下:

typescript 复制代码
// 停止状态类
class StopState implements State {
    @Override
    public void doAction(Context context) {
        System.out.println("Stop State");
        context.setState(new StartState());
    }
}

状态模式设计的关键设计思想在于状态切换,我们引入一个context负责状态管理:

typescript 复制代码
class Context {
    private State state;
​
    public State getState() {
        return state;
    }
​
    public void setState(State state) {
        this.state = state;
    }
​
    public void doAction() {
        state.doAction(this);
    }
}

这样,就完成了一个状态模式的实现,测试下效果:

typescript 复制代码
public class StatePatternDemo {
    public static void main(String[] args) {
        Context context = new Context();
        context.setState(new StartState());
​
        context.doAction(); // Start State -> Run State
        context.doAction(); // Run State -> Stop State
        context.doAction(); // Stop State -> Start State
    }
}

总结

状态模式的设计思想在于把不同的状态逻辑拆分封装到不同的状态类中,从而使得后续增加新状态更容易。

状态模式的实现关键在于状态的切换。状态既可以由调用方负责切换,也可以在状态内部自己根据不同条件完成切换。

相关推荐
麦麦鸡腿堡3 分钟前
Java的抽象类
java·开发语言
Java水解4 分钟前
Go基础:Go语言中 Goroutine 和 Channel 的声明与使用
java·后端·面试
用户41429296072395 分钟前
一文读懂 API:连接数字世界的 “隐形桥梁”
后端
PFinal社区_南丞5 分钟前
别再盲接 OTel:Go 可观察性接入的 8 个大坑
后端
Chan1614 分钟前
流量安全优化:基于 Nacos 和 BloomFilter 实现动态IP黑名单过滤
java·spring boot·后端·spring·nacos·idea·bloomfilter
非凡ghost37 分钟前
PixPin截图工具(支持截长图截动图) 中文绿色版
前端·javascript·后端
武子康38 分钟前
大数据-133 ClickHouse 概念与基础|为什么快?列式 + 向量化 + MergeTree 对比
大数据·后端·nosql
脚踏实地的大梦想家1 小时前
【Go】P11 掌握 Go 语言函数(二):进阶玩转高阶函数、闭包与 Defer/Panic/Recover
开发语言·后端·golang