状态模式

Posted huangyichun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状态模式相关的知识,希望对你有一定的参考价值。

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

 

 

以上是关于状态模式的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家

方向/配置更改后如何维护 ListView 片段状态?

java BottomBarNavigation代码保留片段状态

为不同方向使用不同布局时,在方向更改时保存片段状态

多选模式列表视图行在删除后保持选中状态