大话设计模式——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 策略模式

  • 状态模式重在各个状态之间的切换从而有不同的行为,策略模式重在根据具体情况选择策略不涉及状态的切换
  • 状态模式不同状态做不同的事情且不能相互替换,策略模式解决的都是同一件事
相关推荐
reddingtons6 小时前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
李慕婉学姐7 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆8 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin9 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20059 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉9 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国9 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882489 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈10 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_9910 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc