大话设计模式——17.状态模式(State Pattern)

简介

对象的行为依赖于它的状态(属性),可以根据状态的改变而改变相关行为。

UML图:
应用场景:
  • 对象的行为取决于其状态,并且必须要在运行时刻根据状态而改变行为
  • 代码中包含大量与对象状态有关的条件语句

示例

上午、下午、晚上工作的状态

  1. 上下文对象:
java 复制代码
public class Work {

    /**
     * 工作状态
     */
    private State state;

    /**
     * 当前时间
     */
    private int hour;


    /**
     * 工作是否完成
     */
    private boolean isFinished;


    public Work() {
        // 初始化操作
        this.state = new MorningState();
    }

    public void writeProgram() {
        state.writeProgram(this);
    }


    public State getState() {
        return state;
    }

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

    public int getHour() {
        return hour;
    }

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

    public boolean isFinished() {
        return isFinished;
    }

    public void setFinished(boolean finished) {
        isFinished = finished;
    }
}
  1. 状态
java 复制代码
public interface State {

    void writeProgram(Work work);
}
java 复制代码
public class MorningState implements State {

    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 12) {
            System.out.println("当前时间:" + work.getHour() + ",干劲十足!");
        } else {
            work.setState(new NoonState());
            work.writeProgram();
        }
    }
}
java 复制代码
public class NoonState implements State {

    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 13) {
            System.out.println("当前时间:" + work.getHour() + ",好饿,开始干饭!");
        } else {
            work.setState(new AfternoonState());
            work.writeProgram();
        }
    }
}
java 复制代码
public class AfternoonState implements State {

    @Override
    public void writeProgram(Work work) {
        if (work.getHour() < 18) {
            System.out.println("当前时间:" + work.getHour() + ",开始上班,有点疲惫!");
        } else {
            work.setState(new EveningState());
            work.writeProgram();
        }
    }
}
java 复制代码
public class EveningState implements State {

    @Override
    public void writeProgram(Work work) {
        if (!work.isFinished()) {
            System.out.println("当前时间:" + work.getHour() + ",又要加班");
        } else {
            System.out.println("当前时间:" + work.getHour() + ",下班啦!");
        }
    }
}
  1. 运行
java 复制代码
public class Main {

    public static void main(String[] args) {
        Work work = new Work();
        // 上午
        work.setHour(9);
        work.writeProgram();

        // 中午
        work.setHour(12);
        work.writeProgram();

        // 下午
        work.setHour(16);
        work.writeProgram();

        // 晚上
        work.setHour(18);
//        work.setFinished(true);
        work.writeProgram();
    }
}

总结

  • 优点
    • 只需改变对象的状态,就可改变对象的行为
    • 多个环境对象共享一个状态对象,可以减少系统中对象的个数
  • 缺点
    • 增加系统类和对象的个数
    • 使用不当将造成程序结构和代码的混乱
    • 不符合开闭原则,新增状态需要修改源码

VS 策略模式

  • 状态模式重在各个状态之间的切换从而有不同的行为,策略模式重在根据具体情况选择策略不涉及状态的切换
  • 状态模式不同状态做不同的事情且不能相互替换,策略模式解决的都是同一件事
相关推荐
mghio7 小时前
Dubbo 中的集群容错
java·微服务·dubbo
千千寰宇8 小时前
[设计模式/Java/多线程] 设计模式之单例模式【9】
设计模式·操作系统-进程/线程/并发
咖啡教室12 小时前
java日常开发笔记和开发问题记录
java
咖啡教室12 小时前
java练习项目记录笔记
java
鱼樱前端13 小时前
maven的基础安装和使用--mac/window版本
java·后端
RainbowSea13 小时前
6. RabbitMQ 死信队列的详细操作编写
java·消息队列·rabbitmq
RainbowSea13 小时前
5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
java·消息队列·rabbitmq
李少兄15 小时前
Unirest:优雅的Java HTTP客户端库
java·开发语言·http
此木|西贝15 小时前
【设计模式】原型模式
java·设计模式·原型模式