技术成神之路:设计模式(七)状态模式

2024-07-19 1242阅读

1.介绍


状态模式(State Pattern)是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为。这个模式将状态的相关行为封装在独立的状态类中,并将不同状态之间的转换逻辑分离开来。

2.主要作用


状态模式的主要作用是让一个对象在其内部状态改变时,其行为也随之改变,但同时又使得状态的变化对外部来说是透明的。它将状态转移的逻辑封装在状态类中,使得增加新的状态变得简单,同时避免状态间的相互依赖,使得代码更加清晰。

3.解决的问题


状态模式主要解决的问题是对象在不同状态下的行为变化问题,以及状态转换的复杂性管理。

状态模式可以帮助解决以下几类问题:

  1. 消除大量的条件判断语句:

    我们在项目中会经常用到条件判断语句,而有的对象行为会使用到大量的条件语句(如if-else或switch-case)来实现。在某些情况下条件语句少了还好,多了就是灾难,既不美观,又不优雅,唯一好处就是方便使用,但维护起来不方便,如果不使用状态模式,可能需要在每个操作的实现中加入大量的状态判断,这会导致代码复杂、难以维护和扩展。

  2. 状态转换的管理:

    对象的状态不仅仅影响其行为,还涉及到状态之间的转换逻辑。就算你为了方便使用了 if-else或switch-case ,那么处理转换逻辑的代码要写在哪里,状态模式通过将每种状态封装为一个独立的类,使得状态转换的逻辑局部化,每个状态类负责自己的状态判断和转换条件,从而简化了整体的状态管理。

  3. 提高代码的可读性和可维护性:

    这个没什么好说的,设计模式通用✨

4.模式原理


包含角色:

  1. Context(环境类):定义客户感兴趣的接口,并维护一个具体状态子类的实例,这个实例定义当前状态。
  2. State(状态接口/抽象类):定义一个接口或抽象类,封装与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态类):每一个具体状态类实现了在状态接口中定义的行为,负责状态转换时的逻辑。

了解策略模式的烙铁看到这里是不是很熟悉,包含的角色几乎一模一样,只是把策略两个字改成了状态,那么状态模式是不是就不用继续往下看了?no no no,它们还是有差别滴…

UML类图:

技术成神之路:设计模式(七)状态模式

代码示例:

// State 接口
interface DocumentState {
    void edit(Document doc);
    void save(Document doc);
    void print(Document doc);
}
// ConcreteState 具体状态类
class EditableState implements DocumentState {
    public void edit(Document doc) {
        // 编辑操作
    }
    public void save(Document doc) {
        // 保存操作
    }
    public void print(Document doc) {
        // 打印操作
    }
}
// Context 环境类
class Document {
    private DocumentState currentState;
    
    public Document() {
        this.currentState = new EditableState(); 
    }
    
    public void changeState(DocumentState newState) {
        this.currentState = newState;
    }
    
    public void edit() {
        currentState.edit(this);
    }
    
    public void save() {
        currentState.save(this);
    }
    
    public void print() {
        currentState.print(this);
    }
}
// 使用
Document document = new Document();
document.edit();  
document.save();  
document.print(); 
document.changeState(new ReadOnlyState());
document.edit();  // 无法编辑,状态切换到只读

不知道看到这里,你再回想起策略模式时,是不是还有点迷糊,现在分不清没关系,继续往下看,加深一下印象

状态模式和策略模式区别总结:

  1. 关注点不同:
  • 状态模式关注对象在不同状态下的行为差异,封装了不同状态的行为。
  • 策略模式关注的是算法的不同实现方式,允许算法在不影响客户端的情况下独立变化。
    1. 使用场景不同:
    • 状态模式适用于对象的行为在状态改变时发生改变的情况,状态之间有明显的转换关系。
    • 策略模式适用于客户端需要在多个算法中选择一种时,并且允许在运行时切换算法。
      1. 关系不同:
      • 在状态模式中,状态之间存在特定的状态转换关系,通常由Context类来维护和切换状态。
      • 在策略模式中,各个策略(算法)之间通常是相互独立的,客户端通过选择不同的策略对象来实现不同的行为。

        是不是突然觉得差别还是挺大的嘛,思路一下就清晰了,其实不用理解那么深入,它们的名字就是最大的差异点,通过名字你可以一点一点联想它们的实现方式,这样你就真正理解了设计模式的精髓。

        5.优缺点


        优点

        • 清晰的状态转换:状态模式将状态和行为封装在独立的类中,使状态转换更加清晰。
        • 提高可维护性和扩展性:通过分离状态和行为,代码更加模块化,便于添加新状态和修改现有状态。
        • 减少条件分支:避免了在上下文类中使用大量的条件分支(if-else 或 switch-case)。

          缺点

          • 增加类的数量:每个状态都需要一个类,可能会导致系统中类的数量增加,从而增加维护难度(设计模式通病)。
          • 状态之间的依赖:某些状态可能依赖于其他状态,导致状态类之间的耦合(此条可忽略)。

            6.应用场景


            状态模式 状态模式 首先你得有不同状态才行,举几个简单场景:

            • 对象行为依赖于其状态:如电灯开关、文档编辑器的状态(如草稿、审核中、已发布等)。
            • 状态转换复杂:状态之间存在复杂的转换逻辑,需要清晰地管理状态和行为。
            • 需要频繁更改状态或扩展新状态:如游戏角色的状态、工作流引擎的状态等。

              7.总结


              状态模式通过将状态和状态相关的行为封装在独立的类中,使得状态转换逻辑更加清晰和可维护。它提高了代码的扩展性和可维护性,适用于对象行为依赖于状态且状态转换复杂的场景。然而,需要注意的是,状态模式可能会增加系统中类的数量,使得系统的维护变得更加复杂。在使用状态模式时,需要权衡其带来的好处和潜在的复杂性。

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]