少一点If/Else - 状态模式(State Pattern)

打印 上一主题 下一主题

主题 1047|帖子 1047|积分 3141

状态模式(State Pattern)

状态模式(State Pattern)是一种行为型计划模式,它允许对象在其内部状态改变时改变其行为。这个模式的核心思想是将对象的行为封装在不同的状态类中,每个状态类都实现了雷同接口或继承自同一个抽象类。通过这种方式,当对象的状态发生变化时,它可以动态地更改其行为,避免了大量的条件分支语句(if-else 或 switch-case)。
属实有点抽象,还是举个现实中的例子
我们举一个H2O的例子,H2O是水的化学元素符号。但是水又有一个特点,在温度低于0摄氏度(尺度大气压下面)的情况下,水是以固态的形式存在;温度在100摄氏度以上的时候以气态形式存在;在0摄氏度到100摄氏度之间的时候以液态形式存在。这个例子反应的就是我们本次要介绍的状态模式(State Pattern),即水这个对象在某一个状态转变的时候,以不同的形式存在。
状态模式(State Pattern)概述

状态模式(State Pattern)结构图


状态模式(State Pattern)涉及的角色


  • 情况类(Context):情况类拥有对状态对象的引用,并且提供了客户端访问状态的方法。它还负责管理状态的变化。
  1. public class Context {
  2.     private State state;
  3.     public Context(State state) {
  4.         this.state = state;
  5.     }
  6.     public void setState(State state) {
  7.         this.state = state;
  8.         System.out.println("Current state set to " + state.getClass().getSimpleName());
  9.     }
  10.     public void request() {
  11.         state.handle(this);
  12.     }
  13. }
复制代码

  • 抽象状态(State):这是一个接口或抽象类,声明白所有详细状态必须实现的方法。这些方法定义了不同状态下对象的行为。
  1. public interface State {
  2.     void handle(Context context);
  3. }
复制代码

  • 详细状态(ConcreteState):详细状态实现了State接口,每个详细状态类都包含了与该状态相关的行为逻辑。
  1. public class ConcreteStateA implements State {
  2.     @Override
  3.     public void handle(Context context) {
  4.         System.out.println("Handling request in State A");
  5.         // 改变状态
  6.         context.setState(new ConcreteStateB());
  7.     }
  8. }
  9. public class ConcreteStateB implements State {
  10.     @Override
  11.     public void handle(Context context) {
  12.         System.out.println("Handling request in State B");
  13.         // 改变状态
  14.         context.setState(new ConcreteStateA());
  15.     }
  16. }
复制代码
talk is cheap, show you my code

我们还是利用本次要介绍的状态计划模式来实现我们前面说的谁人例子。
  1. // 抽象状态类
  2. abstract class State {
  3.     protected Water water;
  4.     public State(Water water) {
  5.         this.water = water;
  6.     }
  7.     public abstract void heat();
  8.     public abstract void cool();
  9. }
  10. // 具体状态类:固态
  11. class SolidState extends State {
  12.     public SolidState(Water water) {
  13.         super(water);
  14.     }
  15.     @Override
  16.     public void heat() {
  17.         System.out.println("Water is melting from solid to liquid.");
  18.         water.setState(new LiquidState(water));
  19.     }
  20.     @Override
  21.     public void cool() {
  22.         System.out.println("Water is already in solid state. Cannot cool further.");
  23.     }
  24. }
  25. // 具体状态类:液态
  26. class LiquidState extends State {
  27.     public LiquidState(Water water) {
  28.         super(water);
  29.     }
  30.     @Override
  31.     public void heat() {
  32.         System.out.println("Water is evaporating from liquid to gas.");
  33.         water.setState(new GasState(water));
  34.     }
  35.     @Override
  36.     public void cool() {
  37.         System.out.println("Water is freezing from liquid to solid.");
  38.         water.setState(new SolidState(water));
  39.     }
  40. }
  41. // 具体状态类:气态
  42. class GasState extends State {
  43.     public GasState(Water water) {
  44.         super(water);
  45.     }
  46.     @Override
  47.     public void heat() {
  48.         System.out.println("Water is already in gas state. Cannot heat further.");
  49.     }
  50.     @Override
  51.     public void cool() {
  52.         System.out.println("Water is condensing from gas to liquid.");
  53.         water.setState(new LiquidState(water));
  54.     }
  55. }
  56. // 环境类:水
  57. class Water {
  58.     private State state;
  59.     public Water() {
  60.         state = new SolidState(this); // 假设初始状态为固态
  61.     }
  62.     public void setState(State state) {
  63.         this.state = state;
  64.     }
  65.     public void heat() {
  66.         state.heat();
  67.     }
  68.     public void cool() {
  69.         state.cool();
  70.     }
  71.     public String getState() {
  72.         return state.getClass().getSimpleName().replace("State", "");
  73.     }
  74. }
  75. // 测试类
  76. public class WaterStatePatternDemo {
  77.     public static void main(String[] args) {
  78.         Water water = new Water();
  79.         System.out.println("Current state: " + water.getState());
  80.         water.heat();
  81.         System.out.println("Current state: " + water.getState());
  82.         water.heat();
  83.         System.out.println("Current state: " + water.getState());
  84.         water.cool();
  85.         System.out.println("Current state: " + water.getState());
  86.         water.cool();
  87.         System.out.println("Current state: " + water.getState());
  88.     }
  89. }
复制代码
输出结果
  1. Current state: Solid
  2. Water is melting from solid to liquid.
  3. Current state: Liquid
  4. Water is evaporating from liquid to gas.
  5. Current state: Gas
  6. Water is condensing from gas to liquid.
  7. Current state: Liquid
  8. Water is freezing from liquid to solid.
  9. Current state: Solid
复制代码
在这个例子中,Water类作为情况类持有一个State对象的引用,该对象表示水的当前状态。State是一个抽象类,定义了加热(heat)和冷却(cool)的方法。每种详细状态(固态、液态、气态)都实现了这些方法,并在方法内部包含了状态转换的逻辑。
总结

状态模式的优点


  • 简化对象的操作:状态模式将与特定状态相关的操作封装到状态类中,使得情况类可以专注于其他功能而不必处置处罚复杂的状态逻辑。
  • 遵循开闭原则:新增加的状态只需要创建新的详细状态类,而不需要修改现有的代码,这符合面向对象计划中的开闭原则(Open/Closed Principle)。
  • 淘汰条件语句:通过将不同状态下的行为转移到相应的状态类中,淘汰了情况类中可能出现的大量条件判定语句。
  • 提高可读性和可维护性:每个状态都有本身的类,这有助于更好地组织代码,提高代码的可读性和可维护性。
状态模式重要应用在对象出现出在不同状态显示出不一样的行为的时候。状态模式提供了一种有用的方式来解耦对象与其行为之间的关系,使得对象可以在不破坏封装的条件下,根据其内部状态的变化而改变行为。这对于构建具有复杂状态逻辑的应用程序特殊有用。理解如何正确使用状态模式可以资助开辟者构建更加模块化、机动且易于维护的软件体系。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

反转基因福娃

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表