• 设计模式-状态模式


       本片文章主要介绍状态模式。

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

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

       我们先看下结构图:

        State类,抽象状态类,定义一个接口与Context的一个特定状态相关的行为。

    package com.lwx.state;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:24
     */
    public interface State {
    
        void handle(Context context);
    
    }

        ConcreteState类,集体状态,每一个子类实现一个与Context的一个状态相关的行为。

    package com.lwx.state;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:27
     */
    public class ConcreteStateA implements State {
    
        @Override
        public void handle(Context context) {
            context.setState(new ConcreteStateB());
        }
    
    }
    package com.lwx.state;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:27
     */
    public class ConcreteStateB implements State {
    
        @Override
        public void handle(Context context) {
            context.setState(new ConcreteStateA());
        }
    
    }

        Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。

    package com.lwx.state;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:24
     */
    public class Context {
    
        private State state;
    
        public Context(State state) {
            this.state = state;
        }
    
        public State getState() {
            return state;
        }
    
        public void setState(State state) {
            this.state = state;
            System.out.println("当前状态:" + state.getClass().getName());
        }
    
        public void request() {
            state.handle(this);
        }
    
    }

        然后是测试类和运行结果。

    package com.lwx.state;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:29
     */
    public class Client {
    
        public static void main(String[] args) {
            Context context = new Context(new ConcreteStateA());
            context.request();
            context.request();
            context.request();
            context.request();
        }
    
    }

        可以看到我们没调用一次request()方法就会改变一次状态。

        上面的例子很简单,结构清晰但是理解起来却很生硬,下面我们用大话设计模式一书中的工作状态例子来展示一下。

        我们还是先看下结构图:

         首先是抽象状态类,定义一个抽象方法 “写程序”。

    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 抽象状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:31
     */
    public interface WorkState {
    
        void writeProgram(Work work);
    
    }

        上午和中午工作状态类。

    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 上午工作状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:32
     */
    public class ForenoonState implements WorkState {
    
        @Override
        public void writeProgram(Work work) {
            if (work.getHour() < 12) {
                System.out.println("当前时间:" + work.getHour() + "点 上午工作,精神百倍。");
            } else {
                //超过12点,则转入中午工作状态
                work.setWorkState(new NoonState());
                work.writeProgram();
            }
        }
    }
    package com.lwx.state.example;
    
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 中午工作状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:39
     */
    public class NoonState implements WorkState {
    
        @Override
        public void writeProgram(Work work) {
            if (work.getHour() < 13) {
                System.out.println("当前时间:" + work.getHour() + "点 饿了,午饭;犯困,午休。");
            } else {
                //超过13点,转入下午工作状态
                work.setWorkState(new AfternoonState());
                work.writeProgram();
            }
        }
    
    }

        下午和傍晚工作状态类。

    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 下午工作状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:43
     */
    public class AfternoonState implements WorkState {
    
        @Override
        public void writeProgram(Work work) {
            if (work.getHour() < 17) {
                System.out.println("当前时间:" + work.getHour() + "点 下午状态还不错,继续努力。");
            } else {
                work.setWorkState(new EveningState());
                work.writeProgram();
            }
        }
    
    }
    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 晚间工作状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:45
     */
    public class EveningState implements WorkState {
    
        @Override
        public void writeProgram(Work work) {
            if (work.getFinish() == null ? Boolean.FALSE : work.getFinish()) {
                //完成任务,转入下班状态
                work.setWorkState(new RestState());
                work.writeProgram();
            } else {
                if (work.getHour() < 21) {
                    System.out.println("当前时间:" + work.getHour() + "点 加班哦,疲劳至极。");
                } else {
                    //超过21点则转入睡眠工作状态
                    work.setWorkState(new SleepingState());
                    work.writeProgram();
                }
            }
        }
    
    }

        睡眠状态和下班休息状态类。

    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 睡眠状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:46
     */
    public class SleepingState implements WorkState {
    
        @Override
        public void writeProgram(Work work) {
            System.out.println("当前时间:" + work.getHour() + "点 不行了,睡着了。");
        }
    
    }
    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description: 下班休息状态
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:47
     */
    public class RestState implements WorkState {
    
        @Override
        public void writeProgram(Work work) {
            System.out.println("当前时间:" + work.getHour() + "点 下班回家了。");
        }
    
    }

        工作类。

    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:32
     */
    public class Work {
    
        private WorkState workState;
        // 钟点 属性,状态转化的依据
        private Integer hour;
        // 任务完成 属性,能下班的依据
        private Boolean finish;
    
        public Work() {
            //工作初始化为上午工作状态,即上午9点开始上班
            this.workState = new ForenoonState();
        }
    
        public void writeProgram() {
            workState.writeProgram(this);
        }
    
        public Boolean getFinish() {
            return finish;
        }
    
        public void setFinish(Boolean finish) {
            this.finish = finish;
        }
    
        public Integer getHour() {
            return hour;
        }
    
        public void setHour(Integer hour) {
            this.hour = hour;
        }
    
        public WorkState getWorkState() {
            return workState;
        }
    
        public void setWorkState(WorkState workState) {
            this.workState = workState;
        }
    }

        最后是测试类和运行结果。

    package com.lwx.state.example;
    
    /**
     * Created with IntelliJ IDEA.
     * Description:
     * User: lwx
     * Date: 2019-04-08
     * Time: 21:54
     */
    public class WorkClient {
    
        public static void main(String[] args) {
            Work work = new Work();
            work.setHour(9);
            work.writeProgram();
            work.setHour(10);
            work.writeProgram();
            work.setHour(12);
            work.writeProgram();
            work.setHour(13);
            work.writeProgram();
            work.setHour(14);
            work.writeProgram();
            work.setHour(17);
            work.writeProgram();
    
            work.setFinish(Boolean.TRUE);
    
            work.setHour(19);
            work.writeProgram();
    
            work.setHour(22);
            work.writeProgram();
    
        }
    
    }

        

        状态模式的优点:

          1.将与特定状态相关的行为局部化,并且将不同状态的行为分割化。

          2.状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。

        

        最后附上demo的githup地址:https://github.com/yijinqincai/design_patterns

  • 相关阅读:
    Jquery里live事件移除原因
    js委托事件-addEventListeners(冒泡方向)
    后端同同不肯给我算好的时间差给我,只好自己写了:
    js滚动到顶部底部代码
    浏览器地址栏运行HTML代码(谷歌)
    黑马vue---56-58、vue组件创建的三种方式
    黑马vue---46、vue使用过渡类名实现动画
    黑马vue---28、vue中全局过滤器的基本使用
    vue devtools无法使用
    红心点赞效果的实现
  • 原文地址:https://www.cnblogs.com/leisurexi/p/10673955.html
Copyright © 2020-2023  润新知