博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
行为类模式(八):状态(State)
阅读量:7238 次
发布时间:2019-06-29

本文共 5628 字,大约阅读时间需要 18 分钟。

 

定义

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

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

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         @Override101         public void open()102         {103             System.out.println("电梯门开启...");104         }105 106         @Override107         public void run()108         {109             System.out.println("电梯门开启时不能上下跑!");110         }111 112         @Override113         public void stop()114         {115             // do nothing;116         }117     }118 119     /**120      * 电梯门关闭以后,电梯可以做哪些事情121      */122     public static class ClosingState extends LiftState123     {124         @Override125         public void close()126         {127             System.out.println("电梯门关闭...");128         }129 130         @Override131         public void open()132         {133             super.context.setLiftState(Context.openningState); // 置为门敞状态134             super.context.getLiftState().open();135         }136 137         @Override138         public void run()139         {140             super.context.setLiftState(Context.runningState); // 设置为运行状态;141             super.context.getLiftState().run();142         }143 144         @Override145         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 LiftState156     {157         @Override158         public void close()159         {160             // do nothing161         }162 163         @Override164         public void open()165         {166             // do nothing167         }168 169         @Override170         public void run()171         {172             System.out.println("电梯上下跑...");173         }174 175         @Override176         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 LiftState187     {188         @Override189         public void close()190         {191             // do nothing;192         }193 194         @Override195         public void open()196         {197             super.context.setLiftState(Context.openningState);198             super.context.getLiftState().open();199         }200 201         @Override202         public void run()203         {204             super.context.setLiftState(Context.runningState);205             super.context.getLiftState().run();206         }207 208         @Override209         public void stop()210         {211             System.out.println("电梯停止了...");212         }213     }214 }
View Code

 

转载地址:http://ilrfm.baihongyu.com/

你可能感兴趣的文章
runtime 运行时机制
查看>>
简单区分虚拟主机是linux还是win操作系统
查看>>
检查app的activity是否在当前
查看>>
html5 canvas全屏烟花动画特效
查看>>
MySQL使用SQL实现Oracle Rank函数功能
查看>>
博客搬家
查看>>
xin域名公仔2017版
查看>>
StickyListHeaders的使用
查看>>
云服务器ECS,你真的懂吗?
查看>>
ORA-2330 ORA-01403: no data found
查看>>
学习ssh之ssh密钥随身携带
查看>>
HBA详解(原创)
查看>>
java集合框架02——Collection架构与源码分析
查看>>
怎样检查svn启动没有
查看>>
理解Nodejs的Event Loop
查看>>
Html Table 合并单元格
查看>>
第七章_标签文件
查看>>
阿里巴巴CTO张建锋:大数据+计算+算法才是未来
查看>>
hibernate中一级缓存和二级缓存
查看>>
【转载】架构师的行为准则(一)
查看>>