前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【设计模式】一文快速搞懂状态模式

【设计模式】一文快速搞懂状态模式

原创
作者头像
用户9748554
发布2024-07-08 10:25:56
3220
发布2024-07-08 10:25:56

引入

试着思考下这个功能如何实现:电灯有两种状态:开启(On)和 关闭(Off)。

当电灯处于不同的状态下,按下开关会触发不同的行为:

  • 电灯处于On状态时,按下开关,电灯会处于Off状态;
  • 电灯处于Off状态时,按下开关 ,电灯会处于On状态。

方案一:if-else实现

具体逻辑实现代码

代码语言:Java
复制
class Light {

    // 电灯状态
    private boolean isOn;

    public Light() {
     // 初始状态为关闭
        this.isOn = false; 
    }

   // 不同状态按下开关逻辑
    public void toggleSwitch() {
        if (isOn) {
        // 开启状态按下开关,状态变为关闭
            System.out.println("Light is turned OFF");
            isOn = false;
        } else {
        // 关闭状态按下开关,状态变为开启
            System.out.println("Light is turned ON");
            isOn = true;
        }
    }
}

存在问题

如果电灯添加新的状态,则需要修改toggleSwitch()的逻辑,这种方式的两个弊端 :

  • 如果状态很多,条件语句会越来越多,会导致方法复杂,使代码难以理解和维护;
  • 每次添加状态都需要修改方法,可能会影响现有的状态切换逻辑,容易引入错误 。

新增状态代码实现

假设我们为电灯添加一个新状态,成为调光(Dim)状态,该种状态下 ,电灯的亮度比较低,但仍然是开启状态。

代码语言:Java
复制
class Light {
    private boolean isOn;
    // 新增调光Dim状态
    private boolean isDim;

    public Light() {
        this.isOn = false; // 初始状态为关
        this.isDim = false; // 初始不是调光状态
    }

    public void toggleSwitch() {

       // 增加状态后修改状态转换逻辑
        if (isOn) {
            if (isDim) {
                System.out.println("Light is turned OFF");
                isOn = false;
                isDim = false;
            } else {
                System.out.println("Light is turned Dim");
                isDim = true;
            }
        } else {
            System.out.println("Light is turned ON");
            isOn = true;
        }
    }
}

总结

可以看到,上述例子新增了一个状态,方法的复杂程度就上升了一个级别,如果新增的不是一个状态,而是五个,十个甚至百个呢,这种实现方案明显不是一个好的选择。因此,这种方案只适合状态比较少切换逻辑不是很复杂的情形。

方案二:状态模式实现

代码实现

1. 定义一个状态接口(或抽象类)

代码语言:Java
复制
// 状态接口
interface State {
    void toggleSwitch(Light light);
}

2. 为每个具体状态创建实现类

代码语言:Java
复制
// 具体状态类:灯关闭状态
class OffState implements State {
    @Override
    public void toggleSwitch(Light light) {
        System.out.println("Light is turned ON");
        light.setState(new OnState());
    }
}

// 具体状态类:灯打开状态
class OnState implements State {
    @Override
    public void toggleSwitch(Light light) {
        System.out.println("Light is turned Dim");
        light.setState(new DimState());
    }
}

// 具体状态类:灯调光状态
class DimState implements State {
    @Override
    public void toggleSwitch(Light light) {
        System.out.println("Light is turned OFF");
        light.setState(new OffState());
    }
}

3.电灯将根据当前状态委托相关操作给状态对象

代码语言:Java
复制
// 环境类,电灯
class Light {
    private State state;

    public Light() {
        // 初始状态为关
        this.state = new OffState();
    }

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

    public void toggleSwitch() {
        state.toggleSwitch(this);
    }
}

类图

总结

可以看到,采用状态模式添加新状态代码复杂度大大降低,只需要创建新的实现类并实现 State接口,然后在合适的位置进行状态切换即可。这种设计避免了复杂的条件语句,使代码更加清晰、可维护和可扩展。

状态模式

什么是状态模式

状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的类一样。

状态模式核心概念

  • State(状态):定义一个接口或抽象类,用于封装与上下文相关的行为。
  • ConcreteState(具体状态):实现状态接口或继承抽象状态类,具体定义每个状态下的行为。
  • Context(上下文):维护一个状态对象,并在状态发生变化时改变其行为。
状态模式结构
状态模式结构

优缺点

优点

  • 单一职责原则。 将与特定状态相关的代码放在单独的类中。
  • 开闭原则。 无需修改已有状态类和上下文就能引入新状态。
  • 通过消除臃肿的状态机条件语句简化上下文代码。

缺点

如果只有很少的几个状态, 或者很少发生改变, 那么应用该模式可能会显得小题大作。

参考资料

https://refactoringguru.cn/design-patterns/state


我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引入
  • 方案一:if-else实现
    • 具体逻辑实现代码
      • 存在问题
        • 新增状态代码实现
          • 总结
          • 方案二:状态模式实现
            • 代码实现
              • 1. 定义一个状态接口(或抽象类)
              • 2. 为每个具体状态创建实现类
              • 3.电灯将根据当前状态委托相关操作给状态对象
            • 类图
              • 总结
              • 状态模式
                • 什么是状态模式
                  • 状态模式核心概念
                    • 优缺点
                      • 优点
                      • 缺点
                  • 参考资料
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档