二十三种设计模式第二十三篇--状态模式
  cEe6YWJIAuf2 2023年11月14日 41 0


状态模式,是一种行为模式,在软件开发过程中,对象按照不同的情况做出不同的行为,我们把这样的对象称为具有状态的对象,而把影响对象行为的一个或者多个动态变化的属性称为状态。

对这种具有状态的对象变成,传统的解决方案是,将这些所有可能发生情况全部考虑到,然后使用if-else或者switch-case语句来做状态判断,再进行不同情况的处理。但是这种情况存在一个弊端,就是,条件判断语句会过于浮肿,可读性差,并且不具备拓展性,维护难度也将加大,并且增加新的状态时需要添加新的if-else语句,这违背了“开闭原则”,并不利于程序的拓展。

状态模式:它允许对象在内部状态改变时改变其行为。状态模式将状态和对应的行为封装成不同的状态对象,使得对象的行为可以根据不同的状态进行动态切换。

状态模式的核心组成部分包括:

状态接口(State Interface):定义了状态对象的接口,包含了对象在该状态下可以执行的方法。

具体状态类(Concrete State):实现了状态接口,在具体的状态下定义了对象的行为。

环境类(Context):包含了一个状态对象,并维护当前的状态,可以根据不同的状态调用相应的方法。

状态模式的主要优点包括:

将状态和行为分离:将不同的状态封装成不同的对象,使得状态和行为可以独立变化,提高了代码的灵活性和可维护性。
简化条件语句:通过状态对象的切换来替代复杂的条件语句,使得代码更加清晰和易懂。
符合开闭原则:增加新的状态类不会修改已有的代码,只需要添加新的状态类和相应的转换规则。

关于状态模式的限制和适用场景:
可能增加对象的数量:每个状态都需要一个对应的状态类,可能会增加对象的数量。
当状态比较少且相对简单时,使用状态模式可能会增加代码的复杂性。

状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

二十三种设计模式第二十三篇--状态模式_System

/**
 * 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
 */
public interface State {

   //行为动作...
   public void doAction(Context context);

}
/**
 * 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
 * 这里代表游戏玩家开始的状态.
 */
public class StartState implements State {
 
   @Override
   public void doAction(Context context) {
      System.out.println("玩家处理于启动状态,开始相应操作");
      //给上下文对象设定对应的状态对象,然后在 context执行对应的操作
      // 这里避免了使用 if...else 这样的判断语句.
      context.setState(this);
   }
 
   @Override
   public String toString(){
      return "开始状态";
   }
}
/**
 * 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
 *
 * 状态机
 */
public class Context {
   /**
    *  ******* 状态
    */
   private State state;
 
   public Context(){
      state = null;
   }

   //******状态修改
   public void setState(State state){
      this.state = state;
      //TODO:在这里可以加入 状态修改后的进一步的操作...

      //修改状态  -> 触发事件   -> 消息通知   -> 操作  -> 状态改变.
      //    a   ->  e1       ->    b
      //    b   ->   e2      ->    c


   }
 
   public State getState(){
      return state;
   }
}
public class StatePatternDemo {
   public static void main(String[] args) {

      Context context = new Context();
      //注意比较:  以下状态发生变化时,无须要用  if..else做状态判断.

      //设置状态为开始.
      StartState startState = new StartState();
      startState.doAction(context);
 
      System.out.println(context.getState().toString());

      //修改状态为  stop
      StopState stopState = new StopState();
      stopState.doAction(context);
 
      System.out.println(context.getState().toString());
   }
}
/**
 * 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
 * 停止状态
 */
public class StopState implements State {
 
   @Override
   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      //给上下文对象设定对应的状态对象,然后在 context执行对应的操作
      // 这里避免了使用 if...else 这样的判断语句.
      context.setState(this); 
   }
 
   @Override
   public String toString(){
      return "Stop State";
   }
}

路才刚刚开始走,怎么能半路放弃呢?听我所听,做我想做,梦我想梦,也许几年后我看到这句话会把他删掉,也许他就这么挂在这里,一直挂着。我与众生皆为凡人,无高低贵贱,他擅他长,吾擅吾长,何须羡慕他人等?身在其位,专攻其事,如若不善,辞职跑路!何须压抑与心之久,于己不快哉,长路漫漫有人陪同吾亦乐之,无人陪同吾亦独行,彼岸花开,终有一日,吾亦赏之。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

推荐阅读
  A32uB2Hhmc6N   2023年12月12日   51   0   0 MySQLMySQLideide
cEe6YWJIAuf2