14/24 设计模式之状态模式 State Pattern

815 阅读2分钟

类别:行为型设计模式

目的:对象在不同状态下表现出一组不同的行为,运行状态可以进行切换

完整代码参考:ct0-my.sharepoint.com/:u:/g/perso…

典型场景

角色:护士、患者 场景:患者会根据自生的状态对护士的照顾做出不同的行为

患者处于稳定状态

  1. 护士带患者去散步,患者将处于稳定状态
  2. 给稳定患者供氧,患者将从稳定状态转为不稳定状态

患者处于不稳定状态

  1. 护士带患者去散步,患者将继续处于不稳定状态,情况可能家中
  2. 给稳定患者供氧,患者将从不稳定状态转为稳定状态

模式实现

护士类Nurse.java

public class Nurse {

    PatientStateBehavior state;
    StablePatientStateBehavior stablePatientState = new StablePatientStateBehavior(this);
    UnStablePatientStateBehavior unStablePatientState = new UnStablePatientStateBehavior(this);

    public void setState (PatientStateBehavior state) {
        this.state = state;
    }

    public void supplyOxygen () {
        state.supplyOxygen();
    }

    public void walking() {
        state.walking();
    }
}

患者行为类,稳定状态患者行为StablePatientStateBehavior.java,不稳定患者行为UnStablePatientStateBehavior.java

public interface PatientStateBehavior {

    void supplyOxygen ();

    void walking();

}

class StablePatientStateBehavior implements PatientStateBehavior {

    private Nurse context;

    public StablePatientStateBehavior (Nurse context) {
        this.context = context;
    }

    @Override
    public void supplyOxygen () {
        System.out.println("给稳定的患者供氧可能导致患者变得不稳定");
        context.setState(context.unStablePatientState);
    }

    @Override
    public void walking() {
        System.out.println("让稳定的患者散步可以提高抵抗力");
        context.setState(context.stablePatientState);
    }
}

class UnStablePatientStateBehavior implements PatientStateBehavior {

    private Nurse context;

    public UnStablePatientStateBehavior (Nurse context) {
        this.context = context;
    }

    @Override
    public void supplyOxygen () {
        System.out.println("给不稳定的患者供氧可以让患者变得稳定");
        context.setState(context.stablePatientState);
    }

    @Override
    public void walking() {
        System.out.println("不稳定的患者不需要散步");
        context.setState(context.unStablePatientState);
    }

}

可以看到,给患者执行不同的操作时,患者稳定、不稳定状态之间会根据行为是否合适而发生切换

执行效果如下

var nurse = new Nurse();
System.out.println("初始不稳定的患者:");
nurse.setState(nurse.unStablePatientState);
nurse.supplyOxygen(); // 患者发生状态切换, 不稳定 -> 稳定
nurse.walking();

System.out.println("\n初始稳定的患者:");
nurse.setState(nurse.stablePatientState);
nurse.supplyOxygen(); // 患者发生状态切换, 稳定 -> 不稳定
nurse.walking();

-w460

UML

-w659

一些注意的点

如果不会扩展新的状态,可以使用简单的if else结构

实现同一个接口的对象实际运行的实现可以发生改变而呈现出不同的行为

策略模式执行时自身策略对象不会发生改变,状态模式执行时,自生状态对象会发生改变

状态模式可以处理所有状态的行为,策略模式一般只处理一种行为的不同策略

参考资料

  1. www.geeksforgeeks.org/state-desig…
  2. stackoverflow.com/questions/1…
  3. javarevisited.blogspot.com/2014/04/dif…