状态模式

1. 什么是状态模式

State 模式也叫状态模式,是行为设计模式的一种。 State 模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。

2. 状态模式的应用场景

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。

3. 状态模式的结构

23_状态模式 - 图1

4. 状态模式的角色和职责

  • Context:用户对象拥有一个 State 类型的成员,以标识对象的当前状态。
  • State:接口或基类封装与 Context 的特定状态相关的行为。
  • ConcreteState:接口实现类或子类实现了一个与 Context 某个状态相关的行为。

5. 代码演示

5.1. 不使用状态模式

  1. public class Person {
  2. private int hour;
  3. public int getHour() {
  4. return hour;
  5. }
  6. public void setHour(int hour) {
  7. this.hour = hour;
  8. }
  9. public void doSomething() {
  10. if (hour == 7) {
  11. System.out.println("吃早餐");
  12. } else if (hour == 12) {
  13. System.out.println("吃午饭");
  14. } else if (hour == 18) {
  15. System.out.println("吃晚饭");
  16. } else {
  17. System.out.println(hour + "未定义");
  18. }
  19. }
  20. }
  1. Person person = new Person();
  2. person.setHour(7);
  3. person.doSomething();
  4. person.setHour(12);
  5. person.doSomething();
  6. person.setHour(18);
  7. person.doSomething();
  8. person.setHour(8);
  9. person.doSomething();
  1. 吃早餐
  2. 吃午饭
  3. 吃晚饭
  4. 8未定义

5.2. 使用状态模式

  1. public class Person {
  2. private int hour;
  3. private State state;
  4. // ...
  5. public void doSomething() {
  6. if (hour == 7) {
  7. state = new State7();
  8. } else if (hour == 12) {
  9. state = new State12();
  10. } else if (hour == 18) {
  11. state = new State18();
  12. } else {
  13. state = new NoState();
  14. }
  15. state.doOneThing();
  16. }
  17. }
  1. public abstract class State {
  2. public abstract void doOneThing();
  3. }
  1. public class State7 extends State {
  2. @Override
  3. public void doOneThing() {
  4. System.out.println("吃早餐");
  5. }
  6. }
  1. public class State12 extends State {
  2. @Override
  3. public void doOneThing() {
  4. System.out.println("吃午饭");
  5. }
  6. }
  1. public class State18 extends State {
  2. @Override
  3. public void doOneThing() {
  4. System.out.println("吃晚饭");
  5. }
  6. }
  1. public class NoState extends State {
  2. @Override
  3. public void doOneThing() {
  4. System.out.println("未定义");
  5. }
  6. }

5.3. 改进

  1. public class Person {
  2. private int hour;
  3. private State state;
  4. public Person() {
  5. this.state = new State7();
  6. }
  7. // ...
  8. public void doSomething() {
  9. this.state.doOneThing(this);
  10. this.state = new State7();
  11. }
  12. }
  1. public abstract class State {
  2. public abstract void doOneThing(Person person);
  3. }
  1. public class State7 extends State {
  2. @Override
  3. public void doOneThing(Person person) {
  4. if (person.getHour() == 7) {
  5. System.out.println("吃早餐");
  6. } else {
  7. person.setState(new State12());
  8. person.doSomething();
  9. }
  10. }
  11. }
  1. public class State12 extends State {
  2. @Override
  3. public void doOneThing(Person person) {
  4. if (person.getHour() == 12) {
  5. System.out.println("吃午饭");
  6. } else {
  7. person.setState(new State18());
  8. person.doSomething();
  9. }
  10. }
  11. }
  1. public class State18 extends State {
  2. @Override
  3. public void doOneThing(Person person) {
  4. if (person.getHour() == 18) {
  5. System.out.println("吃晚饭");
  6. } else {
  7. person.setState(new NoState());
  8. person.doSomething();
  9. }
  10. }
  11. }
  1. public class NoState extends State {
  2. @Override
  3. public void doOneThing(Person person) {
  4. System.out.println(person.getHour() + "未定义");
  5. }
  6. }
  1. Person person = new Person();
  2. person.setHour(7);
  3. person.doSomething();
  4. person.setHour(12);
  5. person.doSomething();
  6. person.setHour(18);
  7. person.doSomething();
  8. person.setHour(8);
  9. person.doSomething();
  10. person.setHour(7);
  11. person.doSomething();
  12. person.setHour(18);
  13. person.doSomething();
  1. 吃早餐
  2. 吃午饭
  3. 吃晚饭
  4. 8未定义
  5. 吃早餐
  6. 吃晚饭