状态模式

103 阅读3分钟

定义

是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为。在状态模式中,类的行为会随着所处的状态不同而变化,每一个状态都是一个类,这些状态类封装了与该状态相关的行为,并负责在状态之间进行转换。

优缺点

优点

  1. 封装性良好:将状态相关的逻辑封装到单独的状态类中,使代码更易于理解和维护
  2. 扩展性高:当系统需要增加新的状态或者改变现有状态的行为时,只需要添加新的具体状态类即可,无需修改其他已有代码。
  3. 职责分明:每个状态只关心自己对应状态下的行为,避免了条件判断语句遍布在整个程序中。

缺点

  1. 类数量增加:如果系统的状态较多,可能会导致类的数量迅速增长,从而增加了系统的复杂度。

结构图与代码示例

image.png

  • Context:维护一个ConcreteState实例,负责调用状态对象的处理方法,并根据当前状态对象何时进行状态切换。
  • State(抽象状态类):定义所有具体状态类需要实现的接口,可以包含一个上下文对象,以便在状态发生变化的时候能够访问和修改上下文的状态。
  • ConcreteState(具体状态类):是抽象状态类的子类,实现了在抽象状态类中声明的操作方法。每个具体状态类代表一种具体的系统状态,并负责处理在这种状态下应有的行为以及可能发生的状态转移。
/**
 * 抽象状态
 */
public interface State {
    public void writeProgram(Work w);
}

/**
 * 工作
 */
public class Work {
    // 当前状态
    private State current;
    // 当前时间
    private double hour;
    // 是否已完成
    private boolean isFinish;

    public Work() {
        current = new ForenoonState();
    }

    public State getCurrent() {
        return current;
    }

    public void setCurrent(State current) {
        this.current = current;
    }

    public double getHour() {
        return hour;
    }

    public void setHour(double hour) {
        this.hour = hour;
    }

    public boolean isFinish() {
        return isFinish;
    }

    public void setFinish(boolean finish) {
        isFinish = finish;
    }

    public void writeProgram() {
        current.writeProgram(this);
    }
}
/**
 * 上午工作状态
 */
public class ForenoonState implements State {
    @Override
    public void writeProgram(Work w) {
        if (w.getHour() < 12) {
            System.out.println("当前时间:" + w.getHour() + "点 上午工作,精神百倍");
        } else {
            w.setCurrent(new NoonState());
            w.writeProgram();
        }
    }
}

/**
 * 中午工作状态
 */
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();
        }
    }
}
/**
 * 下午工作状态
 */
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();
        }
    }
}

/**
 * 晚间工作状态
 */
public class EveningState implements State{
    @Override
    public void writeProgram(Work w) {
        if (w.isFinish()) {
            w.setCurrent(new RestState());
            w.writeProgram();
        } else {
            if (w.getHour() < 21) {
                System.out.println("当前时间:" + w.getHour() + "点 加班哦,疲累之极");
            } else {
                w.setCurrent(new SleepingState());
                w.writeProgram();
            }
        }
    }
}

/**
 * 下班状态
 */
public class RestState implements State {
    @Override
    public void writeProgram(Work w) {
        System.out.println("当前时间:" + w.getHour() + "点 下班回家了");
    }
}

/**
 * 睡眠状态
 */
public class SleepingState implements State {
    @Override
    public void writeProgram(Work w) {
        System.out.println("当前时间:" + w.getHour() + "点 不行了,睡着了");
    }
}

public class TestApi {
    public static void main(String[] args) {
        Work project = new Work();
        project.setHour(9);
        project.writeProgram();

        project.setHour(10);
        project.writeProgram();

        project.setHour(12);
        project.writeProgram();

        project.setHour(13);
        project.writeProgram();

        project.setHour(14);
        project.writeProgram();

        project.setHour(17);
        //        project.setFinish(true);
        project.setFinish(false);

        project.writeProgram();

        project.setHour(19);
        project.writeProgram();

        project.setHour(22);
        project.writeProgram();

    }
}