前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >状态模式

状态模式

作者头像
用户1148394
发布2018-01-09 16:58:19
6800
发布2018-01-09 16:58:19
举报
文章被收录于专栏:余林丰

今天要说的设计模式——状态模式,个人觉得非常有意思,因为此种设计模式的运用场景几乎可以说是每个程序里都可以用上。当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。定义一般来说都是晦涩难懂的。我们同样来通俗一点解释,首先解释这种模式的运用场景,这种模式一般用在有大量if-else的分支判断上,不同的状态也就表示为不同的if条件,进入不同的if分支执行操作后就好像是改变了其类。

image.png
image.png

这就是状态模式的UML类结构图,其实在这里看UML类结构图还是有点蒙逼的样子,if-else分支这种场景经常遇到,比如在eclipse里会有一个checkstyle插件,在这个插件可以检查是否分支过多,以前觉得这个分支本来就这么多啊,需要做这么多判断啊,我怎么去拆分。但看了这个状态模式过后才知道其实不然,有大量的if-else分支判断,说明在这个类里它的责任过大,无论任何状态,都需要通过它来改变,而面向对象设计其实就是希望做到代码的责任分解。

我们如果有这么一段if-else代码需要做分解,那该怎么办?

代码语言:javascript
复制
if (hour< 12) {
    System.out.println("状态1:" + hour);
} else if (hour < 18) {
    System.out.println("状态2:" + hour);  
} else {
    System.out.println("状态2:" + hour);  
}

上面的场景中,我们在实际当中可能还会遇到更多的分支。说了那么多,我们直接实现代码来看,状态模式是如何做到将if-else分支分解的。

代码语言:javascript
复制
 1 package day_25_state;
 2 
 3 /**
 4  * 状态接口
 5  * @author turbo
 6  *
 7  * 2016年9月25日
 8  */
 9 public interface State {
10     void handle(Context context);
11 }
代码语言:javascript
复制
 1 package day_25_state;
 2 
 3 /**
 4  * 状态1
 5  * @author turbo
 6  *
 7  * 2016年9月25日
 8  */
 9 public class ConcreteState1 implements State {
10 
11     /* (non-Javadoc)
12      * @see day_25_state.State#handle(day_25_state.Context)
13      */
14     @Override
15     public void handle(Context context) {
16         if (context.getHour() < 13){
17             System.out.println("状态1:时间" + context.getHour());
18         } else {
19             context.setState(new ConcreteState2());
20             context.handle();
21         }
22     }
23 
24 }
代码语言:javascript
复制
 1 package day_25_state;
 2 
 3 /**
 4  * 状态2
 5  * 
 6  * @author turbo
 7  *
 8  * 2016年9月25日
 9  */
10 public class ConcreteState2 implements State {
11 
12     /*
13      * (non-Javadoc)
14      * 
15      * @see day_25_state.State#handle(day_25_state.Context)
16      */
17     @Override
18     public void handle(Context context) {
19         if (context.getHour() < 18) {
20             System.out.println("状态2:时间" + context.getHour());
21         } else {
22             context.setState(new ConcreteState3());
23             context.handle();
24         }
25     }
26 
27 }
代码语言:javascript
复制
 1 package day_25_state;
 2 
 3 /**
 4  * 状态3
 5  * @author turbo
 6  *
 7  * 2016年9月25日
 8  */
 9 public class ConcreteState3 implements State {
10 
11     /* (non-Javadoc)
12      * @see day_25_state.State#handle(day_25_state.Context)
13      */
14     @Override
15     public void handle(Context context) {
16         System.out.println("状态3:" + context.getHour());
17     }
18 
19 }

注意看上面3个具体状态的else分支语句。

下面是是Context类,可以理解为它就是“寻找、判断”当前状态是什么。

代码语言:javascript
复制
 1 package day_25_state;
 2 
 3 /**
 4  * 用来定义当前状态
 5  * @author turbo
 6  *
 7  * 2016年9月25日
 8  */
 9 public class Context {
10     private State state;
11     private double hour;
12     
13     public double getHour() {
14         return hour;
15     }
16 
17     public void setHour(double hour) {
18         this.hour = hour;
19     }
20 
21     public void setState(State state) {
22         this.state = state;
23     }
24 
25     public Context(){
26         state = new ConcreteState1();    //初始化为状态1,可以理解为我们的第一个if判断
27     }
28     
29     public void handle(){
30         state.handle(this);
31     }
32 }

客户端代码:

代码语言:javascript
复制
 1 package day_25_state;
 2 
 3 /**
 4  * 客户端测试代码
 5  * @author turbo
 6  *
 7  * 2016年9月25日
 8  */
 9 public class Main {
10 
11     /**
12      * @param args
13      */
14     public static void main(String[] args) {
15         Context context = new Context();
16         context.setHour(15);
17         context.handle();
18     }
19 
20 }

强烈建议,自己手动敲一遍状态模式的代码,不管看不看得懂代码,但是手敲一遍一定会懂!个人觉得这个模式非常重要和实用,以前从未想过此种用法,从来都是面向过程的思想在写代码,要学的太多,要彻底将面向过程的思维转换为面向对象。前面一开始就说过,面向对象编程,不是用一门面向对象的语言编程。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-09-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档