• 状态模式


    • 状态模式(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();
        }
    }

     

  • 相关阅读:
    文件上传中的错误文件上传及其命名
    播放音乐
    文件的读取与写入ASP.NET中常用代码之四(转载)
    Spring中文在线文档
    Css 图形
    离职进行时
    又面试了
    在Spring应用中创建全局获取ApplicationContext对象
    开始研究WEKA,一个开源java的数据挖掘工具
    收到SZ科技的录取通知,纠结是不是要去
  • 原文地址:https://www.cnblogs.com/huangyichun/p/7098117.html
Copyright © 2020-2023  润新知