美文网首页
20.状态模式

20.状态模式

作者: 0x70e8 | 来源:发表于2018-08-14 20:38 被阅读0次

    [TOC]

    状态模式

    状态模式是使用类来表示一种状态,和通常使用类来表示一个实体不同,这种应用场景下表示的是一个非实体。

    一般而言,一个实体的状态能够影响实体上的行为,如一个人睡着了就不能工作,一个实体的行为反过来又会影响他的状态,工作了就从睡着变成醒来的状态。

    类是有行为的数据,在类里面定义状态可能发生的行为(方法),然后在行为(方法)内判断行为能否发生,并决定是否会影响当前的状态。

    此模式能将代码逻辑从大量的if-else中解脱出来,分散到多个类中。

    示例

    如电梯的上下开关和其状态的关系。

    不使用state模式的伪代码

    // 电梯的状态 开着门open、关着门close、运行中running、静止stop
    // 传入电梯动作(开门open、关门close、运行run、停止stop)
    void act(action){
        if(action is run){
            //判断当前状态
            if(curState is run){
                
            }else if(curState is stop){
                
            }else if(cur is close){
                
            }else{
                // open
            }
            
        }else if(action is stop){
            //判断当前状态
            if(curState is run){
                
            }else if(curState is stop){
                
            }else if(cur is close){
                
            }else{
                // open
            }
        }else if(action is open the door){
            //判断当前状态
            if(curState is run){
                
            }else if(curState is stop){
                
            }else if(cur is close){
                
            }else{
                // open
            }
        }else{//action is close the door
            //判断当前状态
            if(curState is run){
                
            }else if(curState is stop){
                
            }else if(cur is close){
                
            }else{
                // open
            }
        }
    }
    
    

    发现会有大量的if-else语句,且在内部还需要针对action来修改电梯的状态,逻辑很复杂,并且当状态或者行为有新增的时候,将是一场噩梦。

    使用state模式

    使用类表示状态,实际上是封装状态和行为:

    • 状态接口和状态的表示
    public abstract class LiftState {
    
        private StateEnum state;
    
        public abstract void run();
    
        public abstract void stop();
    
        public abstract void close();
    
        public abstract void open();
    
        /**
         * @return the state
         */
        public StateEnum getState() {
            return state;
        }
    
        /**
         * @param state
         *            the state to set
         */
        public void setState(StateEnum state) {
            this.state = state;
        }
    }
    
    public enum StateEnum {
        RUN, STOP, OPEN, CLOSE;
    }
    
    • 具体状态类
    public class LIftCloseState extends LiftState {
        public LIftCloseState() {
            this.setState(StateEnum.CLOSE);
        }
    
        @Override
        public void run() {
            System.out.println("run it!");
            this.setState(StateEnum.RUN);
        }
    
        @Override
        public void stop() {
            System.out.println("stop it");
            this.setState(StateEnum.STOP);
        }
    
        @Override
        public void close() {
            System.out.println("already closed ");
            this.setState(StateEnum.CLOSE);
        }
    
        @Override
        public void open() {
            System.out.println("open it");
            this.setState(StateEnum.OPEN);
    
        }
    
    }
    
    
    public class LIftOpenState extends LiftState {
        public LIftOpenState() {
            this.setState(StateEnum.OPEN);
        }
    
        @Override
        public void run() {
            System.out.println("cannot  run!");
    
        }
    
        @Override
        public void stop() {
            System.out.println("already stop");
            this.setState(StateEnum.STOP);
        }
    
        @Override
        public void close() {
            System.out.println("close it");
            this.setState(StateEnum.CLOSE);
        }
    
        @Override
        public void open() {
            System.out.println("already open");
            this.setState(StateEnum.OPEN);
        }
    
    }
    
    
    public class LIftRunState extends LiftState {
        public LIftRunState() {
            this.setState(StateEnum.RUN);
        }
    
        @Override
        public void run() {
            System.out.println("already run!");
            this.setState(StateEnum.RUN);
        }
    
        @Override
        public void stop() {
            System.out.println("stop it");
            this.setState(StateEnum.STOP);
    
        }
    
        @Override
        public void close() {
            System.out.println("already closed");
            this.setState(StateEnum.CLOSE);
        }
    
        @Override
        public void open() {
            System.out.println("can not open");
    
        }
    
    }
    
    
    public class LIftStopState extends LiftState {
        public LIftStopState() {
            this.setState(StateEnum.STOP);
        }
    
        @Override
        public void run() {
            System.out.println("start run!");
            this.setState(StateEnum.RUN);
        }
    
        @Override
        public void stop() {
            System.out.println("already stop");
            this.setState(StateEnum.STOP);
        }
    
        @Override
        public void close() {
            System.out.println("close the lift");
            this.setState(StateEnum.CLOSE);
        }
    
        @Override
        public void open() {
            System.out.println("open the lift");
            this.setState(StateEnum.OPEN);
    
        }
    
    }
    
    
    • Client
    public class Client {
    
        public static void main(String[] args) {
            LiftState state = new LIftOpenState();
            state.close();
            state.run();
            state.stop();
            state.open();
            state.close();
            state.run();
            state.open();
            state.stop();
    
        }
    
    }
    

    可以发现,状态的判断分散到状态的类中去了,每个状态类维护其上可以发生的行为以及行为会改变的状态。没有了if-else语句,且此情况下,增加一个状态时只需要增加一个类,可能需要修改其他state的方法(影响状态的行为),但是维护起来比if-else方便很多。

    缺点是会产生很多类。

    相关文章

      网友评论

          本文标题:20.状态模式

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