当前位置: 首页 > news >正文

(十 七)趣学设计模式 之 状态模式!

在这里插入图片描述

目录

    • 一、 啥是状态模式?
    • 二、 为什么要用状态模式?
    • 三、 状态模式的实现方式
    • 四、 状态模式的优缺点
    • 五、 状态模式的应用场景
    • 六、 总结

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!
🌟了解责任链模式请看: (十 六)趣学设计模式 之 责任链模式!
✨更多请看个人主页: 码熔burning

这篇文章带你详细认识一下设计模式中的状态模式

一、 啥是状态模式?

想象一下,你正在玩一个游戏 🎮。你的角色会根据不同的情况(比如受伤、正常、加速)而拥有不同的行为和能力。 状态模式就像是给你的角色穿上不同的“衣服”,每件“衣服”代表一种状态,不同的状态决定了角色不同的行为。

状态模式,就是允许对象在内部状态改变时改变它的行为! 它可以将对象的行为封装到不同的状态类中,使得对象可以在不同的状态下表现出不同的行为 🎁。

简单来说,就是让对象像变色龙一样,根据不同的状态,展现不同的行为!

  • 你需要根据对象的状态来改变它的行为: 就像你需要根据角色的状态来决定它的攻击方式 ⚔️!
  • 对象的状态会频繁变化: 就像你需要根据游戏进程不断调整角色的状态 🔄!
  • 你需要避免大量的 if-else 语句来判断对象的状态: 就像你需要避免写一堆代码来判断角色当前应该使用哪种攻击方式 😵‍💫!

二、 为什么要用状态模式?

用状态模式,好处多多 👍:

  • 封装状态和行为: 将每个状态的行为封装到单独的类中,使得代码更加清晰易懂 💫!
  • 易于扩展: 可以方便地添加新的状态,而无需修改现有代码 ➕!
  • 避免大量的 if-else 语句: 使得代码更加简洁优雅 ✨!
  • 提高代码的可维护性: 将每个状态的逻辑封装起来,使得代码更加清晰易懂 💡!

三、 状态模式的实现方式

状态模式主要包含三个核心概念:

  • 环境类(Context): 持有当前状态的引用,并将客户端的请求委托给当前状态处理 🏠!
  • 抽象状态类(State): 定义了所有状态都需要实现的接口,通常包含一个处理请求的方法 🤝!
  • 具体状态类(ConcreteState): 实现了抽象状态类的接口,负责处理特定状态下的请求 ⚙️!
// 环境类:电梯

public class Lift {

    private LiftState state; // 当前状态

    public Lift() {
        this.state = new StopState(); // 初始状态为停止状态
        this.state.setContext(this); // 设置环境类
    }

    public void setState(LiftState state) {
        this.state = state;
        this.state.setContext(this); // 设置环境类
    }

    public LiftState getState() {
        return state;
    }

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

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

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

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

// 抽象状态类:电梯状态

public abstract class LiftState {

    protected Lift context; // 环境类

    public void setContext(Lift context) {
        this.context = context;
    }

    public abstract void open(); // 开门

    public abstract void close(); // 关门

    public abstract void run(); // 运行

    public abstract void stop(); // 停止
}

// 具体状态类:停止状态

public class StopState extends LiftState {

    @Override
    public void open() {
        System.out.println("电梯开门了...");
        context.setState(new OpenState()); // 切换到开门状态
    }

    @Override
    public void close() {
        // 停止状态不能关门
    }

    @Override
    public void run() {
        context.setState(new RunState()); // 切换到运行状态
        System.out.println("电梯开始运行...");
    }

    @Override
    public void stop() {
        System.out.println("电梯停止了...");
    }
}

// 具体状态类:运行状态

public class RunState extends LiftState {

    @Override
    public void open() {
        // 运行状态不能开门
    }

    @Override
    public void close() {
        // 运行状态不能关门
    }

    @Override
    public void run() {
        System.out.println("电梯正在运行...");
    }

    @Override
    public void stop() {
        System.out.println("电梯停止了...");
        context.setState(new StopState()); // 切换到停止状态
    }
}

// 具体状态类:开门状态

public class OpenState extends LiftState {

    @Override
    public void open() {
        System.out.println("电梯门已经打开...");
    }

    @Override
    public void close() {
        System.out.println("电梯关门了...");
        context.setState(new CloseState()); // 切换到关门状态
    }

    @Override
    public void run() {
        // 开门状态不能运行
    }

    @Override
    public void stop() {
        // 开门状态不能停止
    }
}

// 具体状态类:关门状态

public class CloseState extends LiftState {

    @Override
    public void open() {
        // 关门状态不能开门
    }

    @Override
    public void close() {
        System.out.println("电梯门已经关闭...");
    }

    @Override
    public void run() {
        System.out.println("电梯开始运行...");
        context.setState(new RunState()); // 切换到运行状态
    }

    @Override
    public void stop() {
        // 关门状态不能停止
    }
}

// 客户端

public class Client {
    public static void main(String[] args) {
        Lift lift = new Lift();

        lift.open(); // 电梯开门了...
        lift.close(); // 电梯关门了...
        lift.run();  // 电梯开始运行...
        lift.stop(); // 电梯停止了...

        lift.getState().open(); // 电梯开门了...
    }
}

代码解释

  • Lift 类是环境类,持有当前电梯状态的引用,并将客户端的请求委托给当前状态处理。
  • LiftState 类是抽象状态类,定义了所有电梯状态都需要实现的接口,包括 opencloserunstop 方法。
  • StopState 类、RunState 类和 OpenState 类是具体状态类,实现了 LiftState 类的接口,负责处理特定状态下的请求。

输出结果

电梯开门了...
电梯关门了...
电梯开始运行...
电梯停止了...
电梯开门了...

四、 状态模式的优缺点

优点:

  • 封装状态和行为 💫!
  • 易于扩展 ➕!
  • 避免大量的 if-else 语句 ✨!
  • 提高代码的可维护性 💡!

缺点:

  • 状态类增多,增加代码复杂度 😫!
  • 状态切换逻辑可能分散在多个状态类中,不易维护 🤯!

五、 状态模式的应用场景

  • 游戏角色状态: 正常、受伤、死亡等等 🎮!
  • 订单状态: 待支付、已支付、已发货、已完成等等 🛒!
  • TCP 连接状态: 监听、已连接、已关闭等等 🌐!
  • 工作流引擎: 定义任务的不同状态和状态转换 ⚙️!

六、 总结

  • 状态模式就像变色龙,根据不同的状态,展现不同的行为! 🦎
  • 核心概念包括环境类、抽象状态类和具体状态类! 🔑
  • 优点是封装状态和行为、易于扩展、避免大量的 if-else 语句、提高代码的可维护性! 👍
  • 缺点是状态类增多,增加代码复杂度、状态切换逻辑可能分散在多个状态类中,不易维护! 👎
  • 适用于对象的状态会频繁变化,并且需要根据状态来改变其行为的场景! 🎯

希望这篇文章能让你彻底理解状态模式! 💯 祝你学习愉快! 😄
看完请看:(十 八)趣学设计模式 之 观察者模式!

相关文章:

  • 【前端】JavaScript 备忘清单(超级详细!)
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_read_token - 详解(3)
  • 云原生周刊:基于 KubeSphere LuBan 架构打造DeepSeek 插件
  • CSDN博客写作教学(五):从写作到个人IP的体系化构建(完结篇)
  • 【AD】4-8 AD集成库的创建与安装
  • C# 多线程
  • 【JAVA】ThreadPoolTaskExecutor 线程池学习、后端异步、高并发处理
  • 全星 FMEA 软件系统在芯片半导体行业的应用介绍
  • leetcode 56. 合并区间
  • abseil-cpp:环境搭建
  • css3d放置的面板方向不对问题排查
  • 二、QT和驱动模块实现智能家居-----问题汇总1
  • 期权帮|股指期货3月合约交割该如何做?
  • 【华为OD机试真题29.9¥】(E卷,100分) - TLV解码(Java Python JS C++ C )
  • Spring Bean 作用域设置为prototype在并发场景下是否是线程安全的
  • 【含文档+PPT+源码】基于SpringBoot和Vue的编程学习系统
  • 【leetcode hot 100 53】最大子数组和
  • 1278. 分割回文串 III
  • Docker安装Grafana数据可视化平台
  • Linux-计算机网络.udp
  • 习近平抵达莫斯科对俄罗斯进行国事访问并出席纪念苏联伟大卫国战争胜利80周年庆典
  • 金融监管总局:做好2025年小微企业金融服务工作
  • 外交部回应西班牙未来外交战略:愿与之一道继续深化开放合作
  • 上海明后天将迎强风大雨,陆地最大阵风7~9级
  • 世界哮喘日丨张旻:哮喘的整体诊断率不足三成,吸入治疗是重要治疗手段
  • “五一”假期预计全社会跨区域人员流动累计14.67亿人次