zoukankan      html  css  js  c++  java
  • 状态模式

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

      状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。如果这个状态判断很简单,那就是没有必要用"状态模式"了。

    • UML类图 (网上找的)
      • Context环境类:环境类中维护一个State对象,它是定义了当前的状态
      • State抽象状态类
      • ConcreteState(OpenState和CloseState)具体状态类:每一个类封装了一个状态对应的行为。

    • 案例:加班工作一天的状态
     1 package state;
     2 
     3 /**
     4  * Created by huangyichun on 2017/6/30.
     5  */
     6 public class Work {
     7     private int hour;
     8     private boolean finish = false;
     9 
    10     public void writeProgram(){
    11         if (hour < 12) {
    12             System.out.println("当前时间: " + hour + "点 上午工作,精神百倍" );
    13         }else if(hour < 13) {
    14             System.out.println("当前时间: " + hour + "点 饿了, 午饭:犯困,午休。" );
    15         }else if(hour < 17) {
    16             System.out.println("当前时间: " + hour + "点 下午状态还不错,继续努力" );
    17         }else {
    18             if (finish) {
    19                 System.out.println("当前时间: " + hour + "点 下班回家了" );
    20             }else {
    21                 if(hour < 21) {
    22                     System.out.println("当前时间: " + hour + "点 加班哦, 疲惫至极" );
    23                 }else {
    24                     System.out.println("当前时间: " + hour + "点 不行了,睡着了" );
    25                 }
    26             }
    27         }
    28     }
    29 
    30     public boolean isFinish() {
    31         return finish;
    32     }
    33 
    34     public void setFinish(boolean finish) {
    35         this.finish = finish;
    36     }
    37 
    38     public int getHour() {
    39         return hour;
    40     }
    41 
    42     public void setHour(int hour) {
    43         this.hour = hour;
    44     }
    45 }
    • 客户端调用
     1 package state;
     2 
     3 /**
     4  * Created by huangyichun on 2017/6/30.
     5  */
     6 public class Client {
     7     public static void main(String[] args) {
     8 
     9         Work emergencyProject = new Work();
    10         emergencyProject.setHour(9);
    11         emergencyProject.writeProgram();
    12         emergencyProject.setHour(10);
    13         emergencyProject.writeProgram();
    14         emergencyProject.setHour(12);
    15         emergencyProject.writeProgram();
    16         emergencyProject.setHour(13);
    17         emergencyProject.writeProgram();
    18         emergencyProject.setHour(14);
    19         emergencyProject.writeProgram();
    20         emergencyProject.setHour(17);
    21         emergencyProject.writeProgram();
    22 
    23         emergencyProject.setFinish(false);
    24         emergencyProject.setHour(19);
    25         emergencyProject.writeProgram();
    26         emergencyProject.setHour(22);
    27         emergencyProject.writeProgram();
    28     }
    29 }

    采用这种方法实现,产生过多的判断分支,这也意味着它的责任过大,面向对象设计其实就是希望做到代码的责任分解。这个类违背了“单一职责原则”。如果老板规定员工加班最晚到8点,我们则需要修改if语句。

    • 采用状态模式进行重构

      抽象接口

    1 package state;
    2 
    3 /**
    4  * Created by huangyichun on 2017/6/30.
    5  */
    6 public interface State {
    7      void writeProgram(Work w);
    8 }

      具体实现类

     1 package state;
     2 
     3 /**
     4  * Created by huangyichun on 2017/6/30.
     5  */
     6 public class ForenoonState implements State {
     7     @Override
     8     public void writeProgram(Work w) {
     9         if (w.getHour() < 12) {
    10             System.out.println("当前时间: " + w.getHour() + "点 上午工作,精神百倍");
    11         }else {
    12             w.setCurrent(new NoonState());
    13             w.writeProgram();
    14         }
    15     }
    16 }
    package state;
    
    /**
     * Created by huangyichun on 2017/6/30.
     */
    public class NoonState implements State {
        @Override
        public void writeProgram(Work w) {
            if (w.getHour() < 13) {
                System.out.println("当前时间: " + w.getHour() + "点 饿了, 午饭:犯困, 午休。");
            }else {
                w.setCurrent(new AfternoonState());
                w.writeProgram();
            }
        }
    }
    package state;
    
    /**
     * Created by huangyichun on 2017/6/30.
     */
    public class AfternoonState implements State {
        @Override
        public void writeProgram(Work w) {
            if (w.getHour() < 17) {
                System.out.println("当前时间: " + w.getHour() + "点 下午状态还不错,继续努力");
            }else {
                w.setCurrent(new EveningState());
                w.writeProgram();
            }
        }
    }
    package state;
    
    /**
     * Created by huangyichun on 2017/6/30.
     */
    public class EveningState implements State {
        @Override
        public void writeProgram(Work w) {
            if (w.getHour() < 21) {
                System.out.println("当前时间: " + w.getHour() + "点 加班哦,疲累至极");
            }else {
                w.setCurrent(new SleepingState());
                w.writeProgram();
            }
        }
    }
    package state;
    
    /**
     * Created by huangyichun on 2017/6/30.
     */
    public class SleepingState implements State {
        @Override
        public void writeProgram(Work w) {
                System.out.println("当前时间: " + w.getHour() + "点 不行了,睡着了");
        }
    }

     修改后的Work相当于Context类

    package state;
    
    
    /**
     * Created by huangyichun on 2017/6/30.
     */
    public class Work {
        private State current;
        private int hour;
        private boolean finish = false;
    
        public Work() {
            current = new ForenoonState();
        }
    
        public State getCurrent() {
            return current;
        }
    
        public void setCurrent(State current) {
            this.current = current;
        }
    
        public void writeProgram(){
            current.writeProgram(this);
        }
    
        public boolean isFinish() {
            return finish;
        }
    
        public void setFinish(boolean finish) {
            this.finish = finish;
        }
    
        public int getHour() {
            return hour;
        }
    
        public void setHour(int hour) {
            this.hour = hour;
        }
    }

    客户端调用代码不变:

    package state;
    
    /**
     * Created by huangyichun on 2017/6/30.
     */
    public class Client {
        public static void main(String[] args) {
    
            Work emergencyProject = new Work();
            emergencyProject.setHour(9);
            emergencyProject.writeProgram();
            emergencyProject.setHour(10);
            emergencyProject.writeProgram();
            emergencyProject.setHour(12);
            emergencyProject.writeProgram();
            emergencyProject.setHour(13);
            emergencyProject.writeProgram();
            emergencyProject.setHour(14);
            emergencyProject.writeProgram();
            emergencyProject.setHour(17);
            emergencyProject.writeProgram();
    
            emergencyProject.setFinish(false);
            emergencyProject.setHour(19);
            emergencyProject.writeProgram();
            emergencyProject.setHour(22);
            emergencyProject.writeProgram();
        }
    }

     

  • 相关阅读:
    书单
    [转载] 修改WIN10的DNS、以及操作系统和 Web 浏览器清除和刷新 DNS 缓存方法汇总
    【题解】 【集训队作业2018】喂鸽子 minmax容斥+期望dp+补集转化 UOJ449
    【题解】 CF809E Surprise me! 虚树+莫比乌斯反演+狄利克雷卷积
    【题解】 CF1478E Nezzar and Binary String 线段树+时间逆序
    如何处理调用EasyCVR地址集成通过EasyPlayer播放器不能播放的问题?
    智慧能源:智能安防监控技术EasyCVR在石油能源行业中的场景应用
    网络穿透/动态组网工具EasyNTS报错connect refused该如何处理?
    如何处理C++编译webrtc无法成功获取sdp的问题?
    硬核讲解:编译webrtc协议为什么需要turn服务器?
  • 原文地址:https://www.cnblogs.com/huangyichun/p/7098117.html
Copyright © 2011-2022 走看看