美文网首页设计模式程序员
设计模式-状态模式

设计模式-状态模式

作者: 东西的南北 | 来源:发表于2017-09-04 19:08 被阅读39次

    介绍

    状态模式和策略模式是一对双胞胎,他们都属于行为设计模式。状态模式和策略模式都是为具有多种可能情形设计的模式,把不同的处理情形抽象为一个相同的接口,符合对扩展开放,对修改封闭的原则。策略模式封装了一组相关算法,它允许Client在运行时使用可互换的行为;状态模式帮助一个类在不同的状态显示不同的行为。状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而通过从Context中分离出策略或算法,我们可以重用它们。
    状态模式(State Pattern) 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

    TCP协议中的三次握手和四次断开也可以使用状态模式来实现。

    结构图

    这里写图片描述

    时序图

    这里写图片描述

    案例

    我就用工作日的上班时间来举例子
    6种状态

    1. 23点到早上7点
    2. 7点到9点
    3. 9点到12点
    4. 12点到13点
    5. 13点到18点
    6. 18点到23点

    State 抽象类

    public abstract class State {
        
        public abstract void handle(WorkDay workDay);
        
        public void changeState(WorkDay workDay){
            State state = null;
            if (23 < workDay.getHour() || workDay.getHour() <= 7) {
                state = new SleepState();
            }
            if (7 < workDay.getHour() && workDay.getHour() <= 9) {
                state = new EarlyMorningState();
            }
            if (9 < workDay.getHour() && workDay.getHour() <= 12) {
                state = new MorningState();
            }
            if (12 < workDay.getHour() && workDay.getHour() <= 13) {
                state = new MiddayState();
            }
            if (13 < workDay.getHour() && workDay.getHour() < 18) {
                state = new AfternoonState();
            }
            if (18 < workDay.getHour() && workDay.getHour() <= 23) {
                state = new NightState();
            }
            
            workDay.setState(state);
            workDay.doWork();
        }
    }
    

    23点到早上7点睡觉状态SleepState

    public class SleepState extends State {
    
        @Override
        public void handle(WorkDay workDay) {
            if (23 < workDay.getHour() || workDay.getHour() <= 7) {
                System.out.println("现在是" + workDay.getHour() + "点,晚上睡觉时间!");
            } else {
                changeState(workDay);
            }
        }
    
    }
    

    **7点到9点清晨状态EarlyMorningState **

    public class EarlyMorningState extends State {
    
        @Override
        public void handle(WorkDay workDay) {
            if (7 < workDay.getHour() && workDay.getHour() <= 9) {
                System.out.println("现在是" + workDay.getHour() + "点,清晨,准备上班!");
            } else {
                changeState(workDay);
            }
        }
    
    }
    

    9点到12点上午上班状态MorningState

    public class MorningState extends State{
        @Override
        public void handle(WorkDay workDay) {
            if (9 < workDay.getHour() && workDay.getHour() <= 12) {
                System.out.println("现在是" + workDay.getHour() + "点,上午工作时间!");
            } else {
                changeState(workDay);
            }
        }
    }
    

    12点到13点中午休息状态MiddayState

    public class MiddayState extends State {
        @Override
        public void handle(WorkDay workDay) {
            if (12 < workDay.getHour() && workDay.getHour() <= 13) {
                System.out.println("现在是"+workDay.getHour()+"点,中午休息时间!");
            } else {
                workDay.setState(new NightState());
                workDay.doWork();
            }
        }
    }
    

    13点到18点下午工作状态AfternoonState

    public class AfternoonState extends State {
    
        @Override
        public void handle(WorkDay workDay) {
            if (13 < workDay.getHour() && workDay.getHour() <= 18) {
                System.out.println("现在是" + workDay.getHour() + "点,下午工作时间!");
            } else {
                changeState(workDay);
            }
        }
    }
    

    18点到23点晚上下班状态NightState

    public class NightState extends State {
    
        @Override
        public void handle(WorkDay workDay) {
            if (18 < workDay.getHour() && workDay.getHour() <= 23) {
                System.out.println("现在是" + workDay.getHour() + "点,晚上下班时间!");
            } else {
                changeState(workDay);
            }
        }
    }
    

    工作日类WorkDay

    public class WorkDay {
        private State state = new NightState();
        private int hour;
    
        public State getState() {
            return state;
        }
    
        public void setState(State state) {
            this.state = state;
        }
    
        public int getHour() {
            return hour;
        }
    
        public void setHour(int hour) {
            this.hour = hour;
        }
        
        public void doWork(){
            state.handle(this);
        }
    }
    

    调用类Client

    public class Client {
        public static void main(String[] args) {
            WorkDay workDay = new WorkDay();
            for (int i = 0; i < 55; i++) {
                workDay.setHour(i%24);
                workDay.doWork();
            }
        }
    }
    

    运行结果


    这里写图片描述

    总结

    在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化。
    环境类实际上就是拥有状态的对象,环境类有时候可以充当状态管理器(State Manager)的角色,可以在环境类中对状态进行切换操作。
    抽象状态类可以是抽象类,也可以是接口,不同状态类就是继承这个父类的不同子类,状态类的产生是由于环境类存在多个状态,同时还满足两个条件: 这些状态经常需要切换,在不同的状态下对象的行为不同。因此可以将不同对象下的行为单独提取出来封装在具体的状态类中,使得环境类对象在其内部状态改变时可以改变它的行为,对象看起来似乎修改了它的类,而实际上是由于切换到不同的具体状态类实现的。由于环境类可以设置为任一具体状态类,因此它针对抽象状态类进行编程,在程序运行时可以将任一具体状态类的对象设置到环境类中,从而使得环境类可以改变内部状态,并且改变行为。

    相关文章

      网友评论

        本文标题:设计模式-状态模式

        本文链接:https://www.haomeiwen.com/subject/kyaejxtx.html