12.状态模式

news2024/11/15 13:43:06

文章目录

  • 状态模式
  • 总结


状态模式

介绍

状态模式它允许一个对象在其内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要目的是将对象的状态封装成不同的类,并将对象的行为委托给当前状态。

组成

  1. Context(环境): 维护一个对具体状态的引用,维护一个状态对象,并将与状态相关的操作委托给当前状态对象。
  2. State(状态): 定义一个接口或抽象类,封装了与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态): 实现了State接口,每个具体状态类都提供了在状态改变时处理的具体行为。

结构图

在这里插入图片描述

场景

假设我们有一个订单处理系统,订单在不同的状态下可以执行不同的操作,比如创建、支付、发货、完成等

版本1.0

// 不使用状态模式的订单类
class OrderWithoutState {
    private String state;

    public OrderWithoutState() {
        // 初始状态为创建状态
        state = "Created";
    }

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

    public void processOrder() {
        if ("Created".equals(state)) {
            System.out.println("Order created, waiting for payment");
            // 可以执行创建订单后的其他逻辑
        } else if ("Paid".equals(state)) {
            System.out.println("Payment received, preparing for shipment");
            // 可以执行支付后的其他逻辑
        } else if ("Shipped".equals(state)) {
            System.out.println("Order shipped, waiting for confirmation");
            // 可以执行发货后的其他逻辑
        } else if ("Completed".equals(state)) {
            System.out.println("Order completed, thank you for your purchase");
            // 可以执行订单完成后的其他逻辑
        }
    }
}
// 客户端
public class WithoutStatePatternExample {
    public static void main(String[] args) {
        OrderWithoutState order = new OrderWithoutState();

        // 创建订单
        order.processOrder();

        // 支付订单
        order.setState("Paid");
        order.processOrder();

        // 发货
        order.setState("Shipped");
        order.processOrder();

        // 完成订单
        order.setState("Completed");
        order.processOrder();
    }
}

问题

上面的实现中,订单类包含一个表示状态的字符串属性,通过条件语句判断当前订单状态,并执行相应的逻辑。这种实现方式会导致代码中出现大量的条件判断,难以维护,并且不符合开闭原则,当需要添加新的订单状态时,需要修改原有的代码。

使用状态模式版本

// 状态接口
interface OrderState {
    void processOrder(OrderContext context);
}
// 具体状态1:创建状态
class CreatedState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Order created, waiting for payment");
        // 可以执行创建订单后的其他逻辑
    }
}

// 具体状态2:支付状态
class PaidState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Payment received, preparing for shipment");
        // 可以执行支付后的其他逻辑
    }
}

// 具体状态3:发货状态
class ShippedState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Order shipped, waiting for confirmation");
        // 可以执行发货后的其他逻辑
    }
}

// 具体状态4:完成状态
class CompletedState implements OrderState {
    @Override
    public void processOrder(OrderContext context) {
        System.out.println("Order completed, thank you for your purchase");
        // 可以执行订单完成后的其他逻辑
    }
}
// 环境类:订单上下文
class OrderContext {
    private OrderState currentState;

    public OrderContext() {
        // 初始状态为创建状态
        currentState = new CreatedState();
    }

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

    public void processOrder() {
        currentState.processOrder(this);
    }
}
// 客户端
public class StatePatternExample {
    public static void main(String[] args) {
        OrderContext order = new OrderContext();

        // 创建订单
        order.processOrder();

        // 支付订单
        order.setState(new PaidState());
        order.processOrder();

        // 发货
        order.setState(new ShippedState());
        order.processOrder();

        // 完成订单
        order.setState(new CompletedState());
        order.processOrder();
    }
}

在这个版本的实现中,我们定义了订单的不同状态,并使用状态模式来处理订单状态的变化。每个具体状态类都实现了 OrderState 接口,提供了处理订单的具体逻辑。OrderContext 类是环境类,维护了当前订单的状态,并通过委托给当前状态对象来执行相应的操作。


总结

优点

  1. 封装性好: 将每个状态封装到一个类中,使得每个状态的实现对其他状态都是独立的,更容易添加新的状态。

  2. 可扩展性好: 容易添加新的状态类,符合开闭原则。

  3. 避免了使用大量的条件语句: 状态模式将不同状态的逻辑分离,避免了使用大量的条件语句来判断当前状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1439747.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaScript】Js中一些数组常用API总结

目录 前言 会改变原数组 push() pop()和shift() unshift() splice() sort() reverse() 不会改变原数组 slice() concat() filter() forEach() toString join(分隔符) 小结 前言 Js中数组是一个重要的数据结构,它相比于字符串有更多的方法…

【RT-DETR有效改进】利用SENetV1重构化网络结构 (ILSVRC冠军得主)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本文给大家带来的改进机制是SENet(Squeeze-and-Excitation Networks)其是一种通过调整卷积网络中的通道关系来提升性能的网络结构。SENet并不是一个独立的网络模型,而是一个可以和现有的任何一个模型相结合…

Unity SRP 管线【第十讲:SRP/URP 图形API】

Unity 封装的图形API 文章目录 Unity 封装的图形API一、 CommandBuffer 要执行的图形命令列表1. CommandBuffer 属性2. CommandBuffer 常用图形API(方法)(1)设置(2)获取临时纹理 GetTemporaryRT以及释放(3)设置纹理为渲染目标 SetRenderTarget(4)Command…

一键放置柱子护角,你get了吗?

今天写个番外篇,给柱子添加护角。 记得几年前刚开始做BIM的时候,有次做车库导视方案模型,记得好像是鼎伦设计的车库一体化方案,当时柱子护角就给了两种方案,而且基本上每颗柱子上都要放护角,然后甲方竟然要…

MySQL8.0 最新版下载安装,手把手式的教程,小白都能安装成功!!

1、打开MySQL数据库官网的下载地址,根据自己的操作系统下载对应的安装包。我这里是Windows的,操作步骤如下: https://dev.mysql.com/downloads/installer/2、选择不登录下载 3、等待下载完成 4、然后点击下载下来的安装包 5、选择安装类型,Custom自定义安装 6、接…

【从Python基础到深度学习】1. Python PyCharm安装及激活

前言: 为了帮助大家快速入门机器学习-深度学习,从今天起我将用100天的时间将大学本科期间的所学所想分享给大家,和大家共同进步。【从Python基础到深度学习】系列博客中我将从python基础开始通过知识和代码实践结合的方式进行知识的分享和记…

Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)

一、概述 ① 缓存穿透:大量请求根本不存在的key(下文详解) ② 缓存雪崩:redis中大量key集体过期(下文详解) ③ 缓存击穿:redis中一个热点key过期(大量用户访问该热点key,…

【Git】08 多人单分支协作场景

文章目录 一、场景1:不同人修改不同文件1.1 场景描述1.2 场景复现1.2.1 克隆到本地1.2.2 新建分支1.2.3 B修改、提交与推送1.2.4 A修改与提交1.2.5 B再次修改并推送1.2.6 A推送报错 1.3 解决 二、场景2:不同人修改同文件的不同区域2.1 场景描述2.2 场景复…

canvas实现涂鸦画板功能

查看专栏目录 canvas实例应用100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

HarmonyOS SDK 助力新浪新闻打造精致易用的新闻应用

原生智能是HarmonyOS NEXT的核心亮点之一,依托HarmonyOS SDK丰富全面的开放能力,开发者只需通过几行代码,即可快速实现AI功能。新浪新闻作为鸿蒙原生应用开发的先行者之一,从有声资讯入手,基于Speech Kit朗读控件上线听…

大模型为什么会有 tokens 限制?

人是以字数来计算文本长度,大语言模型 (LLM)是以 token 数来计算长度的。LLM 使用 token 把一个句子分解成若干部分。 token 可以是一个单词、一个单词中的一个部分、甚至是一个字符,具体取决于它使用的标记化方法 (tokenization…

基于麻雀优化算法优化XGBoost参数的优化控制策略

目录 一、背景 二、算法流程图 三、附录 一、背景 为提高极端梯度提升(Extreme Gradient Boosting, XGBoost)集成算法在时间预测、信贷风险预测、工件参数预测、故障诊断预测等方面中的准确性,研究者提出了一种改进的麻雀算法(…

相机图像质量研究(7)常见问题总结:光学结构对成像的影响--镜片固化

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…

07-OpenFeign-HTTP压缩优化

gzip是一种数据格式,采用用deflate算法压缩数据;gzip是一种流行的数据压缩算法,应用十分广泛,尤其是在Linux平台。 当GZIP压缩到一个纯文本数据时,效果是非常明显的,大约可以减少70%以上的数据…

QTabWidget和QTabBar控件样式设置(qss)

QTabWidget和QTabBar控件样式设置 1、QTabWidget样式可自定义的有哪些示例:效果图 2、QTabBar样式可自定义的有哪些示例效果图 1、QTabWidget样式可自定义的有哪些 QTabWidget::pane{} 定义tabWidgetFrameQTabWidget::tab-bar{} 定义TabBar的位置QTabWidget::tab{}定…

【最详解】如何进行点云的凹凸缺陷检测(opene3D)(完成度80%)

文章目录 前言实现思路想法1想法2想法3 补充实现想法1想法2代码 想法3代码 总结 前言 读前须知: 首先我们得确保你已经完全知晓相关的基本的数学知识,其中包括用最小二乘法拟合曲二次曲面,以及曲面的曲率详细求解。若还是没弄清楚&#xff0…

《幻兽帕鲁》攻略:0基础入门及游戏基础操作 幻兽帕鲁基础设施 幻兽帕鲁基础攻击力 Mac苹果电脑玩幻兽帕鲁 幻兽帕鲁加班加点

今天就跟大家聊聊《幻兽帕鲁》攻略:0基础入门及游戏基础操作。 如果想在苹果电脑玩《幻兽帕鲁》记得安装CrossOver哦。 以下纯干货: CrossOver正版安装包(免费试用):https://souurl.cn/Y1gDao 一、基础操作 二、界面…

稳压二极管应用电路

稳压二极管比较特殊,基本结构与普通二极管一样,也有一个PN结。由于制造工艺的不同,当这种PN结处于反向击穿状态时,PN结不会损坏(普通二极管的PN结是会损坏),在稳压二极管用来稳定电压时就是利用它的这一击穿特性。 由…

【学网攻】 第(23)节 -- PPP协议

系列文章目录 目录 系列文章目录 文章目录 前言 一、PPP协议是什么? 二、实验 1.引入 实验目的 实验背景你是某公司的网络管理员,现在需要与另一个公司进行通信,需要你配置PPP协议保证双方发送的人是真正的而非黑客 技术原理 实验步骤新建Pack…

MySQL学习记录——유 表的约束

文章目录 1、了解2、空属性3、默认值default4、列描述comment就是注释,desc看不到,show能看到。5、zerofill6、主键7、自增长auto_increment8、唯一键9、外键 1、了解 只有数据类型的约束肯定不够,mysql还有表的约束来进而保证数据合法性。约…