zoukankan      html  css  js  c++  java
  • 行为类模式(八):状态(State)

    定义

    当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

    状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

    UML

    优点

    1. 把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
    2. 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
    3. 通过把各种状态转移逻辑分不到状态与其子类之间,来减少相互间的依赖。

    缺点

    1. 每个具体状态类都会产生一个新类,所以会增加系统需要维护的类的数量。可以使用工厂方法来解决。

    应用场景

    1. 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
    2. 一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

    示例

    实现一个电梯运行的程序,电梯的几个状态之前可以相互切换,但是状态的改变有前置条件,比如电梯的开门状态下是不能上下跑的。

    Java

      1 public class Main
      2 {
      3     public static void main(String[] args)
      4     {
      5         Context context = new Context();
      6         context.setLiftState(new ClosingState());
      7         context.open();
      8         context.close();
      9         context.run();
     10         context.stop();
     11 
     12         context.open();
     13         context.run();
     14     }
     15 
     16     public static class Context
     17     {
     18         // 定义出所有的电梯状态
     19         public final static OpenningState openningState = new OpenningState();
     20         public final static ClosingState closingState = new ClosingState();
     21         public final static RunningState runningState = new RunningState();
     22         public final static StoppingState stoppingState = new StoppingState();
     23 
     24         // 定一个当前电梯状态
     25         private LiftState liftState;
     26 
     27         public LiftState getLiftState()
     28         {
     29             return liftState;
     30         }
     31 
     32         public void setLiftState(LiftState liftState)
     33         {
     34             this.liftState = liftState;
     35             // 把当前的环境通知到各个实现类中
     36             this.liftState.setContext(this);
     37         }
     38 
     39         public void open()
     40         {
     41             this.liftState.open();
     42         }
     43 
     44         public void close()
     45         {
     46             this.liftState.close();
     47         }
     48 
     49         public void run()
     50         {
     51             this.liftState.run();
     52         }
     53 
     54         public void stop()
     55         {
     56             this.liftState.stop();
     57         }
     58     }
     59 
     60     /**
     61      * 定义一个电梯的接口
     62      */
     63     public static abstract class LiftState
     64     {
     65         // 定义一个环境角色,也就是封装状态的变换引起的功能变化
     66         protected Context context;
     67 
     68         public void setContext(Context _context)
     69         {
     70             this.context = _context;
     71         }
     72 
     73         // 首先电梯门开启动作
     74         public abstract void open();
     75 
     76         // 电梯门有开启,那当然也就有关闭了
     77         public abstract void close();
     78 
     79         // 电梯要能上能下,跑起来
     80         public abstract void run();
     81 
     82         // 电梯还要能停下来,停不下来那就扯淡了
     83         public abstract void stop();
     84     }
     85 
     86     /**
     87      * 在电梯门开启的状态下能做什么事情
     88      */
     89     public static class OpenningState extends LiftState
     90     {
     91         @Override
     92         public void close()
     93         {
     94             // 状态修改
     95             super.context.setLiftState(Context.closingState);
     96             // 动作委托为CloseState来执行
     97             super.context.getLiftState().close();
     98         }
     99 
    100         @Override
    101         public void open()
    102         {
    103             System.out.println("电梯门开启...");
    104         }
    105 
    106         @Override
    107         public void run()
    108         {
    109             System.out.println("电梯门开启时不能上下跑!");
    110         }
    111 
    112         @Override
    113         public void stop()
    114         {
    115             // do nothing;
    116         }
    117     }
    118 
    119     /**
    120      * 电梯门关闭以后,电梯可以做哪些事情
    121      */
    122     public static class ClosingState extends LiftState
    123     {
    124         @Override
    125         public void close()
    126         {
    127             System.out.println("电梯门关闭...");
    128         }
    129 
    130         @Override
    131         public void open()
    132         {
    133             super.context.setLiftState(Context.openningState); // 置为门敞状态
    134             super.context.getLiftState().open();
    135         }
    136 
    137         @Override
    138         public void run()
    139         {
    140             super.context.setLiftState(Context.runningState); // 设置为运行状态;
    141             super.context.getLiftState().run();
    142         }
    143 
    144         @Override
    145         public void stop()
    146         {
    147             super.context.setLiftState(Context.stoppingState); // 设置为停止状态;
    148             super.context.getLiftState().stop();
    149         }
    150     }
    151 
    152     /**
    153      * 电梯在运行状态下能做哪些动作
    154      */
    155     public static class RunningState extends LiftState
    156     {
    157         @Override
    158         public void close()
    159         {
    160             // do nothing
    161         }
    162 
    163         @Override
    164         public void open()
    165         {
    166             // do nothing
    167         }
    168 
    169         @Override
    170         public void run()
    171         {
    172             System.out.println("电梯上下跑...");
    173         }
    174 
    175         @Override
    176         public void stop()
    177         {
    178             super.context.setLiftState(Context.stoppingState);
    179             super.context.getLiftState().stop();
    180         }
    181     }
    182 
    183     /**
    184      * 在停止状态下能做什么事情
    185      */
    186     public static class StoppingState extends LiftState
    187     {
    188         @Override
    189         public void close()
    190         {
    191             // do nothing;
    192         }
    193 
    194         @Override
    195         public void open()
    196         {
    197             super.context.setLiftState(Context.openningState);
    198             super.context.getLiftState().open();
    199         }
    200 
    201         @Override
    202         public void run()
    203         {
    204             super.context.setLiftState(Context.runningState);
    205             super.context.getLiftState().run();
    206         }
    207 
    208         @Override
    209         public void stop()
    210         {
    211             System.out.println("电梯停止了...");
    212         }
    213     }
    214 }
    View Code
  • 相关阅读:
    如何写出无法维护的代码
    阅读优秀代码是提高开发人员修为的一种捷径
    防止代码变质的思考与方法
    干掉你程序中的僵尸代码
    如何防止代码腐烂
    迈出单元测试的第一步
    使用VC6.0编译C++代码的时候报错:fatal error C1071: unexpected end of file found in comment(Mark ZZ)
    Android中onTouch方法的执行过程以及和onClick执行发生冲突的解决办法
    Java中JNI的使用详解第三篇:JNIEnv类型中方法的使用
    Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释
  • 原文地址:https://www.cnblogs.com/hammerc/p/4743814.html
Copyright © 2011-2022 走看看