当前位置: 首页 > news >正文

设计模式二十一:状态模式(State Pattern)

一个对象的内部状态发生变化时,允许对象改变其行为。这种模式使得一个对象看起来好像在运行时改变了它的类,主要目的是将状态的行为从主要对象中分离出来,使得主要对象不必包含所有状态的逻辑,而是将每个状态的行为封装在独立的类中。这有助于减少代码的重复,提高代码的可维护性和可扩展性。

状态模式的使用场景

  1. 对象的行为随着其内部状态的改变而改变
    如果一个对象的行为取决于其内部的状态,并且在运行时可能会频繁地改变状态,那么状态模式可以使得对象的行为更加灵活和易于管理。
  2. 对象有多个状态,每个状态有不同的行为
    当一个对象具有多个状态,并且不同状态下有不同的行为时,状态模式可以帮助将这些不同的行为分离到不同的状态类中,从而保持代码的清晰度和可维护性。
  3. 避免条件语句的过多嵌套
    状态模式可以减少代码中的条件语句嵌套,使代码更加易读,更易于扩展和维护。
  4. 状态转换的规则复杂且多变
    如果对象的状态转换规则非常复杂,可能会随着需求的变化而频繁修改,那么状态模式可以将状态转换逻辑集中到具体的状态类中,减少对主要对象的影响。
  5. 对象的状态可以在运行时动态改变
    状态模式允许对象在运行时切换状态,而且可以相对容易地添加新的状态类。
  6. 避免在主要对象中堆积大量的条件逻辑
    使用状态模式可以将每个状态的逻辑封装在独立的状态类中,避免在主要对象中堆积大量的状态相关的条件逻辑。

状态模式的主要角色

状态模式涉及三个主要角色:Context(上下文)、State(状态)、ConcreteState(具体状态)。状态模式的基本思想是将对象的状态封装成独立的状态类,使得对象的行为可以根据其状态的变化而改变。Context对象通过委托当前状态的行为,实现了在不同状态下的不同行为。
在使用状态模式时,Context对象通常会持有一个当前状态的引用,该引用会在运行时改变。当Context的行为需要根据状态变化而变化时,它会调用当前状态对象的方法,从而实现相应的行为。状态对象之间的切换可以在Context内部进行,或者由外部控制

  1. Context(上下文)
    Context是拥有状态的对象,它维护一个指向当前状态的引用。在状态模式中,Context的行为会随着其内部状态的改变而改变。Context类在使用状态模式时负责将请求委托给当前状态对象。它也可以提供一些方法来允许状态对象改变Context的当前状态。
  2. State(状态)
    State是一个抽象类或接口,定义了具体状态类需要实现的方法。这些方法代表了在特定状态下对象可能执行的行为。Context通过调用这些方法来委托实际的行为给当前状态对象。
  3. ConcreteState(具体状态)
    具体状态类是State的子类,实现了State接口中定义的方法。每个具体状态类都代表Context在特定状态下的行为。通过具体状态类,可以封装和维护特定状态下的行为逻辑。

状态模式java代码实例

假设我们有一个文档编辑器,可以处于三种状态:编辑状态、只读状态和锁定状态。每种状态下,文档编辑器的行为不同。
State接口

public interface EditorState {void type(String content);
}

具体状态

public class EditingState implements EditorState{@Overridepublic void type(String content) {System.out.println("当前处于编辑状态,编辑中......"+content);}}public class LockedState implements EditorState{@Overridepublic void type(String content) {System.out.println("当前处于锁定状态,无法编辑");}
}public class ReadOnlyState implements  EditorState{@Overridepublic void type(String content) {System.out.println("当前处于仅阅读状态,无法编辑");}
}

上下文

public class Editor {private EditorState currentState;public Editor() {this.currentState = new EditingState(); // 初始状态为编辑状态}public void setState(EditorState state) {this.currentState = state;}public void type(String content) {currentState.type(content);}
}

客户端

public class State {public static void main(String[] args) {Editor editor = new Editor();editor.type("七夕快乐!");editor.setState(new ReadOnlyState());editor.type("七夕快乐!");editor.setState(new LockedState());editor.type("七夕快乐!");}}

输出

当前处于编辑状态,编辑中......七夕快乐!
当前处于仅阅读状态,无法编辑
当前处于锁定状态,无法编辑

状态模式的优缺点

状态模式作为一种设计模式,具有一些优点和缺点,下面是它们的总结:
优点:

  1. 清晰的状态管理:状态模式将不同状态的行为封装在独立的状态类中,使得状态之间的转换变得清晰,减少了代码的混乱和重复。
  2. 可维护性和扩展性:由于每个状态都是一个独立的类,当需要添加新的状态时,只需要新增一个状态类,而不需要修改现有的代码。这有助于提高系统的可维护性和可扩展性。
  3. 消除大量的条件语句:状态模式可以消除大量的条件语句,从而使代码更加简洁和易于理解。状态切换的逻辑被封装在状态类内部,避免了在主要对象中堆积复杂的条件判断。
  4. 符合开闭原则:添加新的状态类不会影响到已有的代码,符合开闭原则,即对扩展开放,对修改关闭。

缺点:

  1. 增加了类的数量:引入状态模式会增加系统中的类的数量,尤其在状态较多时,可能会导致类的数量过多,增加代码量。
  2. 可能引起混乱:当状态较多时,可能会增加代码的复杂性,需要仔细管理状态之间的转换逻辑,以避免出现混乱。
  3. 不适用于简单情况:对于仅有几种状态且状态转换逻辑简单的情况,引入状态模式可能会过于复杂,不切实际。
  4. 态之间的耦合:虽然状态模式将状态之间的行为分离,但状态之间的切换仍然存在一定的耦合,需要通过Context类来进行状态的切换,可能会影响一定的灵活性。
http://www.lryc.cn/news/135323.html

相关文章:

  • 【校招VIP】产品思维能力之产品设计
  • 微信小程序卡片横向滚动竖图
  • SpringBoot项目(支付宝整合)——springboot整合支付宝沙箱支付 从极简实现到IOC改进
  • 【AIGC】一款离线版的AI智能换脸工具V2.0分享(支持图片、视频、直播)
  • 管理类联考——逻辑——真题篇——按知识分类——汇总篇——一、形式逻辑——选言——相容选言——或
  • Git如何操作本地分支仓库?
  • WPS右键新建没有docx pptx xlsx 修复
  • 【巧学C++之西游篇】No.2 --- C++闹天宫,带着“重载“和“引用“
  • 【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)
  • KaiwuDB CTO 魏可伟:回归用户本位,打造“小而全”的数据库
  • 行业追踪,2023-08-22
  • 浏览器安装selenium驱动,以Microsoft Edge安装驱动为例
  • 边缘计算网关是如何提高物联网的效率的?
  • AWVS安装~Windows~激活
  • ATFX汇市:杰克逊霍尔年会降至,鲍威尔或再发鹰派言论
  • Zipkin开源的分布式链路追踪系统
  • java 项目运行时,后端控制台出现空指针异常---java.lang.NullPointerException
  • 模型数据处理-数据放入 session和@ModelAttribute 实现 prepare 方法详细讲解
  • 关于android studio 几个简单的问题说明
  • angular常用命令
  • uni-app打包后安卓不显示地图及相关操作详解
  • elelementui组件
  • 什么是安全测试报告,怎么获得软件安全检测报告?
  • JS中的Ajax
  • ImportError: cannot import name ‘SQLDatabaseChain‘ from ‘langchain‘解决方案
  • npm、yarn和pnpm
  • SparkSQL源码分析系列02-编译环境准备
  • 【计算机网络】日志与守护进程
  • 设计模式之职责链模式(ChainOfResponsibility)的C++实现
  • CGAL Mesh(网格数据)布尔操作