状态模式原理剖析

《状态模式原理剖析》

状态模式(State Pattern) 是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。换句话说,当对象状态发生变化时,它的行为也会随之变化。
通过状态模式,可以消除通过 if-else 或 switch-case 来判断状态的需要。每个状态的行为封装在独立的类中

核心思想

状态模式将对象的不同状态封装成独立的类,并让对象在不同的状态下有不同的行为。状态模式通过将状态的行为和逻辑封装在状态类中,使得状态之间的转换变得清晰、易扩展。

UML 类图:状态模式

在这里插入图片描述

角色说明

  1. Context(上下文类)
    • 持有一个 State 对象,表示当前的状态。
    • 负责将状态的转换委托给具体的状态类。
  2. State(抽象状态类)
    • 定义了一个 handle() 方法,用于处理当前状态的逻辑。
  3. ConcreteState(具体状态类)
    • 实现 State 接口,负责在具体状态下的行为。
    • 不同的具体状态类表示对象在不同状态下的不同行为。

案例:订单状态管理

场景描述:

在电商平台或者订餐系统中,订单的状态是一个典型的使用状态模式的场景。订单的状态通常包括以下几种:

  • 新订单NewOrder):订单刚创建。
  • 已付款Paid):订单已付款,等待发货。
  • 已发货Shipped):订单已经发货,等待确认收货。
  • 已完成Completed):订单交易完成。
  • 取消订单Cancelled):订单被取消。

每个订单的状态都会影响订单的行为。例如,只有在新订单状态下,用户才可以取消订单;在已付款状态下,用户不能取消订单,但可以查询发货状态;而在已完成取消状态下,订单是不可修改的。

状态模式处理的好处:

  1. 避免复杂的 if-else 条件判断:不同状态下的订单行为各不相同,使用状态模式可以避免在代码中出现大量的 if-else 条件判断(如:if(order.status == "paid") { ... } else if(order.status == "shipped") { ... })。
  2. 状态行为封装:将每种状态的行为封装到相应的状态类中,使得状态切换清晰,便于维护和扩展。
  3. 提高扩展性:当需要新增或修改订单状态时,可以通过新增状态类而不影响现有代码逻辑,符合开闭原则。

代码实现:订单状态管理

Step 1: 定义状态接口

我们首先定义一个 OrderState 接口,声明了订单状态下的所有可能的行为,比如支付、发货、取消和完成

// 状态接口:订单状态
public interface OrderState {void pay(OrderContext context);void ship(OrderContext context);void cancel(OrderContext context);void complete(OrderContext context);
}

Step 2: 实现具体的状态类

新订单状态(NewOrderState)

当订单处于新订单状态时,可以进行支付或取消操作,但不能发货或完成。

// 具体状态类:新订单状态
public class NewOrderState implements OrderState {@Overridepublic void pay(OrderContext context) {System.out.println("Order paid. Moving to Paid state.");context.setState(new PaidOrderState());}@Overridepublic void ship(OrderContext context) {System.out.println("Cannot ship order. Order is not paid yet.");}@Overridepublic void cancel(OrderContext context) {System.out.println("Order cancelled.");context.setState(new CancelledOrderState());}@Overridepublic void complete(OrderContext context) {System.out.println("Cannot complete order. Order is not paid yet.");}
}

已付款状态(PaidOrderState)

当订单处于已付款状态时,可以发货,但不能取消订单。

// 具体状态类:已付款状态
public class PaidOrderState implements OrderState {@Overridepublic void pay(OrderContext context) {System.out.println("Order is already paid.");}@Overridepublic void ship(OrderContext context) {System.out.println("Order shipped. Moving to Shipped state.");context.setState(new ShippedOrderState());}@Overridepublic void cancel(OrderContext context) {System.out.println("Cannot cancel. Order is already paid.");}@Overridepublic void complete(OrderContext context) {System.out.println("Cannot complete order. Order is not shipped yet.");}
}

已发货状态(ShippedOrderState)

当订单处于已发货状态时,可以完成订单,但不能再发货或取消订单。

// 具体状态类:已发货状态
public class ShippedOrderState implements OrderState {@Overridepublic void pay(OrderContext context) {System.out.println("Order is already paid and shipped.");}@Overridepublic void ship(OrderContext context) {System.out.println("Order is already shipped.");}@Overridepublic void cancel(OrderContext context) {System.out.println("Cannot cancel. Order is already shipped.");}@Overridepublic void complete(OrderContext context) {System.out.println("Order completed. Moving to Completed state.");context.setState(new CompletedOrderState());}
}

已完成状态(CompletedOrderState)

订单已经完成后,所有操作都无法再进行。

// 具体状态类:已完成状态
public class CompletedOrderState implements OrderState {@Overridepublic void pay(OrderContext context) {System.out.println("Cannot pay. Order is already completed.");}@Overridepublic void ship(OrderContext context) {System.out.println("Cannot ship. Order is already completed.");}@Overridepublic void cancel(OrderContext context) {System.out.println("Cannot cancel. Order is already completed.");}@Overridepublic void complete(OrderContext context) {System.out.println("Order is already completed.");}
}

取消订单状态(CancelledOrderState)

订单被取消后,所有操作都无法再进行。

// 具体状态类:取消订单状态
public class CancelledOrderState implements OrderState {@Overridepublic void pay(OrderContext context) {System.out.println("Cannot pay. Order is cancelled.");}@Overridepublic void ship(OrderContext context) {System.out.println("Cannot ship. Order is cancelled.");}@Overridepublic void cancel(OrderContext context) {System.out.println("Order is already cancelled.");}@Overridepublic void complete(OrderContext context) {System.out.println("Cannot complete. Order is cancelled.");}
}

Step 3: 创建上下文类

OrderContext 持有订单的当前状态,并且通过调用当前状态的行为方法来执行操作。

// 上下文类:订单上下文
public class OrderContext {private OrderState currentState;public OrderContext() {this.currentState = new NewOrderState(); // 初始状态为新订单}public void setState(OrderState state) {this.currentState = state;}public void pay() {currentState.pay(this);}public void ship() {currentState.ship(this);}public void cancel() {currentState.cancel(this);}public void complete() {currentState.complete(this);}
}

Step 4: 测试状态模式

public class OrderStatePatternDemo {public static void main(String[] args) {OrderContext order = new OrderContext();// 订单状态:新订单order.pay();       // 支付订单order.ship();      // 发货订单order.complete();  // 完成订单// 尝试取消已完成订单order.cancel();    // 无法取消已完成订单}
}

输出结果

Order paid. Moving to Paid state.
Order shipped. Moving to Shipped state.
Order completed. Moving to Completed state.
Cannot cancel. Order is already completed.

状态模式解决的问题

  1. 避免条件判断的复杂性
    • 如果不使用状态模式,代码中会充满大量的 if-elseswitch-case 条件判断。状态模式将这些判断逻辑分散到各个状态类中,避免了复杂的条件分支。
  2. 清晰的状态转换逻辑
    • 状态模式将状态和行为封装在状态类中,所有的状态转换逻辑都非常清晰。状态的变化和行为的变化是分开的,彼此不干扰。
  3. 遵循开闭原则
    • 新的状态和行为可以通过增加新的状态类实现,而不需要修改已有的状态逻辑,符合开闭原则,便于扩展。

总结

状态模式 是一种强大的设计模式,尤其适合在对象状态频繁变化行为因状态不同而变化的场景中。在订单状态管理的案例中,状态模式帮助我们将订单在不同状态下的行为封装起来,使得代码更加灵活、清晰,同时提高了代码的可扩展性。

通过状态模式,开发者可以轻松应对复杂的状态转换逻辑,并在不修改已有代码的前提下添加新的状态,保证系统的灵活性和扩展性。

优点

  1. 遵循开闭原则
    • 新增状态类时,不需要修改现有的上下文类或状态类,可以轻松扩展系统的状态和行为。
  2. 清晰的状态转换
    • 将状态转换的逻辑封装在各自的状态类中,使得状态之间的切换更加清晰且易于维护。
  3. 消除复杂的条件判断
    • 通过状态模式,消除了通过 if-elseswitch-case 来判断状态的需要。每个状态的行为封装在独立的类中。

缺点

  1. 类的数量增加
    • 每种状态都有一个对应的类,可能导致类的数量急剧增加,增加系统的复杂性。
  2. 状态切换逻辑可能复杂
    • 如果系统中状态过多,且状态间的转换规则复杂,可能会增加状态管理的难度。

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

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

相关文章

计241 作业2:C程序设计初步

问题 A: C语言实验——计算AB&#xff08;顺序结构&#xff09; 思路讲解: 这个直接计算ab就好&#xff0c;没有什么困难的&#xff0c;用来熟悉环境最适合不过 代码实现: #include<stdio.h>int main() {int a,b;scanf("%d %d",&a,&b);printf("…

[JavaEE] IP协议

目录 一、 IP协议 1.1 基本概念 1.2 协议头格式 1.3 特殊IP 二、 地址管理 2.1 网段划分 2.2 CIDR(Classless Interdomain Routing) 2.3 私有IP地址和公网IP地址 2.4 NAT(Network Address Translation)-网络地址转换 2.5 路由选择 三、数据链路层 3.1 认识以太网 3…

监控易监测对象及指标之:全面监控Sybase_New数据库

随着企业数据量的不断增长和业务的复杂化&#xff0c;数据库的稳定性和性能成为了保障业务连续性的关键因素。Sybase_New数据库作为众多企业选择的数据管理解决方案&#xff0c;其稳定性和性能对于企业的运营至关重要。 为了确保Sybase_New数据库的稳定运行和高效性能&#xff…

【CSS in Depth 2 精译_042】6.4 CSS 中的堆叠上下文与 z-index(下)——深入理解堆叠上下文

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09;第二章 相对单位&#xff08;已完结&#xff09;第三章 文档流与盒模型&#xff08;已完结&#xff09;第四章 Flexbox 布局&#xff08;已…

Adobe Photoshop 2024 v25.12 (macOS, Windows) 发布下载 - 照片和设计软件

Adobe Photoshop 2024 v25.12 (macOS, Windows) - 照片和设计软件 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、Lightroom Classic、Media Encoder、Photoshop、Premiere Pro、Adobe XD…

【unity进阶知识3】封装一个事件管理系统

前言 框架的事件系统主要负责高效的方法调用与数据传递&#xff0c;实现各功能之间的解耦&#xff0c;通常在调用某个实例的方法时&#xff0c;必须先获得这个实例的引用或者新实例化一个对象&#xff0c;低耦合度的框架结构希望程序本身不去关注被调用的方法所依托的实例对象…

收银系统源码-ERP进销存解决方案

收银系统目前已经成为门店日常经营的必备软件工具&#xff0c;功能一般需涵盖线下门店收银&#xff0c;ERP进销存、线上商城等。一套好的ERP进销存模块也能很大程度帮助门店经营管理门店。 ERP进销存功能涵盖了商品的采购、销售、调拨、盘点、库存管理、资金管理等全链路管理&…

对话总结:Scale AI的创始人兼CEO Alex Wang

AI的三大支柱 计算:主要由大公司如NVIDIA推动。算法:顶尖实验室如OpenAI主导。数据:Scale致力于推动数据进展。前沿数据的重要性 与人类智能相比较,前沿数据是AI发展的关键。互联网数据是机器与人类合作的结果。语言模型的发展 第一阶段:原始的Transformer论文和GPT的小规…

初识ZYNQ——FPGA学习笔记15

一、ZYNQ简介 ZYNQ&#xff1a;Zynq-7000 All Programmable SoC&#xff08;APSoC&#xff09;&#xff0c;赛灵思公司&#xff08;AMD Xilinx&#xff09;推出的新一代全可编程片上系统 PS&#xff1a;Processing System&#xff0c;处理系统 PL&#xff1a;Program Logic&…

html TAB切换按钮变色、自动生成table--使用函数优化结构

<!DOCTYPE html> <head> <meta charset"UTF-8"> <title>Dynamic Tabs with Table Data</title> <style> /* 简单的样式 */ .tab-content { display: none; border: 1px solid #ccc; padding: 1px; marg…

RTA-OS Port Guide学习(三)-基于S32K324 OS

文章目录 前言HardwareSupported DevicesRegister UsageInitializationModificationRequired OS resourcesInterruptsInterrupt Priority LevelsAllocation of ISRs to Interrupt VectorsVector TableWriting Category 1 Interrupt HandlersWriting Category 2 Interrupt Handl…

Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)

0x01 漏洞描述&#xff1a; Qualitor 8.20及之前版本存在命令注入漏洞&#xff0c;远程攻击者可利用该漏洞通过PHP代码执行任意代码&#xff0c;利用难度较低危害较大。 0x02 影响版本&#xff1a; Qualitor < 8.20 0x03 搜索语句&#xff1a; Fofa:app"Qualitor-…

服务运营 | 运营前沿:生成式AI改变医疗保健的运作方式

编者按 人工智能正在重塑医疗保健的运作方式&#xff0c;减少医生负担并优化病人的就医体验。从解答患者疑问到开发新药&#xff0c;人工智能正在快速革新医疗保健这一行业。编者团队此次将关注《哈佛商业评论》于2023年11月27日发布的文章《GenAI Could Transform How Health …

数字乡村解决方案-3

1. 国家大数据战略与数字乡村 中国第十三个五年规划纲要强调实施国家大数据战略&#xff0c;加快建设数字中国&#xff0c;推进数据资源整合和开放共享&#xff0c;保障数据安全&#xff0c;以大数据助力产业转型升级和提高社会治理的精准性与有效性。 2. 大数据与数字经济 …

【韩顺平Java笔记】第2章:Java概述

按视频的标号来对应小标题&#xff0c;自用学习笔记 文章目录 5. 内容梳理6. 程序举例6.1 什么是程序 7. Java故事7.1 Java诞生小故事7.2 Java技术体系平台 8. Java特性8.1 Java重要特点 9. sublime10. jdk介绍10.1 Java运行机制及运行过程10.1.1 Java虚拟机&#xff08;JVM&a…

无人机飞手入伍当兵技术优势分析

随着现代战争形态的不断演变&#xff0c;无人机技术在军事领域的应用日益广泛&#xff0c;成为提升军队作战能力的重要手段。对于无人机飞手而言&#xff0c;其专业技能和实战经验在入伍当兵后能够转化为显著的技术优势&#xff0c;为国防事业贡献重要力量。以下是从专业技能优…

【学习笔记】TLS/SSL握手之Records

TLS / SSL会话是由记录&#xff08;Records&#xff09;所组成&#xff0c;有4种records HandshakeAlertChange Cipher SpecApplication DataHandshake和Alert Records被分为子类型&#xff08;Subtypes&#xff09;&#xff1a; Handshake&#xff1a;Client HelloHandshake&a…

Miniforge详细安装教程(macOs和Windows)

(注&#xff1a;主要是解决商业应用anaconda收费问题&#xff0c;这是轻量级的代替&#xff0c;个人完全可以使用anaconda和miniconda) Miniforge 是一个轻量级的包管理器&#xff0c;类似于 Anaconda 和 Miniconda。它主要用于安装基于 conda 的 Python 环境&#xff0c;专注于…

Java新手指南:从菜鸟到编程大师的趣味之路-多态

这里是Themberfue 本章讲的是Java三大特性之一的多态&#xff0c;也是最后一个特性 多态概念 既然我们要学习多态&#xff0c;首先得知道这玩意儿到底是个什么东西&#xff1f; 通俗地说&#xff0c;多态其实就是多种形态。具体来说就是去完成某个行为&#xff0c;当不同的对象…

Secret Configmap

应用启动过程中可能需要一些敏感信息&#xff0c;比如访问数据库的用户名&#xff0c;密码或者秘钥&#xff0c;讲这些信息直接保存在容器镜像中显然不合适&#xff0c;kubernetes提供的解决方案就是Secret Secret会以密文的方式存储数据&#xff0c;避免了直接在配置文件中保…