状态模式的理解和实践

        在软件开发中,我们经常遇到需要根据对象的不同状态执行不同行为的情况。如果直接将这些状态判断和行为逻辑写在同一个类中,会导致该类变得臃肿且难以维护。为了解决这个问题,状态模式(State Pattern)应运而生。状态模式是一种行为设计模式,它允许对象在内部状态改变时改变它的行为,避免了大量的条件分支语句,使代码更加清晰和易于管理。

 

一、状态模式的基本概念

        状态模式的核心思想是将对象的行为封装在不同的状态对象中,每个状态对象都有一个共同的抽象状态基类。对象的行为随着其内部状态的改变而改变,而状态的改变是通过状态对象之间的转换来实现的。

        状态模式包含以下几个角色:

  1. Context(环境类):持有当前状态对象的引用,可以维护一个状态对象,并在需要的时候委托状态对象处理请求。
  2. State(抽象状态类):定义一个接口,用于封装与Context的一个特定状态相关的行为。
  3. ConcreteState(具体状态类):实现抽象状态类,每个具体状态类对应Context的一个具体状态,并在其中实现与该状态相关的行为。

二、状态模式的优点

  1. 结构清晰:将状态相关的行为封装在状态类中,避免了大量的条件分支语句,使代码更加清晰。
  2. 易于扩展:新增状态或修改状态行为时,只需新增或修改状态类,无需修改Context类。
  3. 符合开闭原则:对扩展开放,对修改关闭。

三、状态模式的缺点

  1. 类数目增多:状态类数目较多,增加了系统的复杂性。
  2. 状态转换逻辑复杂:如果状态转换逻辑复杂,状态类之间的依赖关系可能会变得复杂。

四、状态模式的实践

        下面我们以一个简单的例子来演示状态模式的应用。假设我们有一个订单系统,订单有不同的状态:待支付、已支付、已发货、已完成。每个状态下订单的行为是不同的,例如待支付状态下可以支付,已支付状态下可以发货,已发货状态下可以确认收货等。

1. 定义抽象状态类

        首先,我们定义一个抽象状态类OrderState,它包含一个处理请求的方法handle

public abstract class OrderState {protected OrderContext orderContext;public OrderState(OrderContext orderContext) {this.orderContext = orderContext;}public abstract void handle(String request);
}


2. 定义具体状态类

        然后,我们为每个状态定义一个具体状态类,例如PendingPaymentStatePaidStateShippedStateCompletedState

public class PendingPaymentState extends OrderState {public PendingPaymentState(OrderContext orderContext) {super(orderContext);}@Overridepublic void handle(String request) {if ("pay".equals(request)) {System.out.println("Order is being paid...");orderContext.setState(new PaidState(orderContext));System.out.println("Order has been paid.");} else {System.out.println("Invalid request for this state: " + request);}}
}public class PaidState extends OrderState {public PaidState(OrderContext orderContext) {super(orderContext);}@Overridepublic void handle(String request) {if ("ship".equals(request)) {System.out.println("Order is being shipped...");orderContext.setState(new ShippedState(orderContext));System.out.println("Order has been shipped.");} else {System.out.println("Invalid request for this state: " + request);}}
}public class ShippedState extends OrderState {public ShippedState(OrderContext orderContext) {super(orderContext);}@Overridepublic void handle(String request) {if ("confirm".equals(request)) {System.out.println("Order is being confirmed...");orderContext.setState(new CompletedState(orderContext));System.out.println("Order has been completed.");} else {System.out.println("Invalid request for this state: " + request);}}
}public class CompletedState extends OrderState {public CompletedState(OrderContext orderContext) {super(orderContext);}@Overridepublic void handle(String request) {System.out.println("Order is already completed. No further actions can be taken.");}
}


3. 定义环境类

        接下来,我们定义环境类OrderContext,它持有当前状态对象的引用,并在需要的时候委托状态对象处理请求。

public class OrderContext {private OrderState state;public OrderContext() {this.state = new PendingPaymentState(this);}public void setState(OrderState state) {this.state = state;}public void handle(String request) {state.handle(request);}public static void main(String[] args) {OrderContext orderContext = new OrderContext();orderContext.handle("pay");orderContext.handle("ship");orderContext.handle("confirm");orderContext.handle("confirm"); // Invalid request for this state}
}


4. 运行结果

        运行OrderContextmain方法,输出结果如下:

Order is being paid...
Order has been paid.
Order is being shipped...
Order has been shipped.
Order is being confirmed...
Order has been completed.
Invalid request for this state: confirm


总结

        状态模式通过将对象的行为封装在不同的状态对象中,使对象的行为随着其内部状态的改变而改变。状态模式避免了大量的条件分支语句,使代码更加清晰和易于维护。同时,状态模式也符合开闭原则,对扩展开放,对修改关闭。

        在实际应用中,状态模式适用于对象的行为依赖于其状态,并且状态之间可以相互转换的场景。例如,订单处理系统、工作流引擎、游戏角色状态管理等。

        需要注意的是,状态模式会增加类的数目,并且如果状态转换逻辑复杂,状态类之间的依赖关系可能会变得复杂。因此,在使用状态模式时,需要权衡其优缺点,根据具体场景选择合适的设计模式。

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

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

相关文章

【MySQL — 数据库基础】MySQL的安装与配置 & 数据库简单介绍

数据库基础 本节目标 掌握关系型数据库,数据库的作用掌握在Windows和Linux系统下安装MySQL数据库了解客户端工具的基本使用和SQL分类了解MySQL架构和存储引擎 1. 数据库的安装与配置 1.1 确认MYSQL版本 处理无法在 cmd 中使用 mysql 命令的情况&a…

Python从入门到入狱

Python是从入门到入狱?这个充满调侃意味的说法在程序员圈子里流传甚广。表面看,它似乎是在嘲笑这门语言从简单易学到深陷麻烦的巨大反差,实际上却隐藏着很多值得深思的问题。要解读这个话题,得从Python的特点、使用场景以及潜在风…

Linux获取文件属性

目录 stat函数 获取文件属性 获取文件权限 实现“head -n 文件名”命令的功能 编程实现“ls -l 文件名”功能 stat/fstat/lstat的区别? stat函数 int stat(const char *path, struct stat *buf); 功能:获取文件属性 参数: path&…

线程信号量 Linux环境 C语言实现

既可以解决多个同类共享资源的互斥问题&#xff0c;也可以解决简易的同步问题 头文件&#xff1a;#include <semaphore.h> 类型&#xff1a;sem_t 初始化&#xff1a;int sem_init(sem_t *sem, int pshared, unsigned int value); //程序中第一次对指定信号量调用p、v操…

如何使用k8s安装minio呢

话不多说&#xff0c;直接干货。 创建 minio-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata:name: miniolabels:app: minio spec:replicas: 1selector:matchLabels:app: miniotemplate:metadata:labels:app: miniospec:containers:- name: minioimage: reg…

设计模式:17、单件模式(单例模式)

目录 0、定义 1、单件模式的一个角色 2、单件模式的UML类图 3、示例代码 0、定义 保证一个类仅有一个实例&#xff0c;并提供一个访问它的全局访问点。 1、单件模式的一个角色 单件类&#xff08;Singleton&#xff09;:单件类只可以创建出一个实例。 2、单件模式的UML类…

前端常用缓存技术深度剖析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

任务管理法宝:甘特图详解

在项目管理中&#xff0c;如何清晰、直观地展示项目的进度和任务分配&#xff1f; 甘特图作为一种经典的项目管理工具&#xff0c;提供了有效的解决方案。无论是团队合作还是个人项目管理&#xff0c;甘特图都能帮助你轻松追踪各项任务的进展。今天&#xff0c;我们将详细介绍…

leetcode 62.不同路径

1.题目要求: 2.解题思路: 利用动态规划去解此题 3.题目代码: class Solution { public:int uniquePaths(int m, int n) {//创建dp数组vector<vector<int>> dp;dp.resize(m);for(int i 0;i < dp.size();i){dp[i].resize(n);}//确定dp数组的含义//初始化for(i…

电子应用设计方案-38:智能语音系统方案设计

智能语音系统方案设计 一、引言 智能语音系统作为一种便捷、自然的人机交互方式&#xff0c;正逐渐在各个领域得到广泛应用。本方案旨在设计一个高效、准确、功能丰富的智能语音系统。 二、系统概述 1. 系统目标 - 实现高准确率的语音识别和自然流畅的语音合成。 - 支持多种语…

UE5 C++ 不规则按钮识别,复选框不规则识别 UPIrregularWidgets

插件名称&#xff1a;UPIrregularWidgets 插件包含以下功能 你可以点击任何图片&#xff0c;而不仅限于矩形图片。 UPButton、UPCheckbox 基于原始的 Button、Checkbox 扩展。 复选框增加了不规则图像识别功能&#xff0c;复选框增加了悬停事件。 欢迎来到我的博客 记录学习过…

第32天:安全开发-JavaEE应用Servlet路由技术JDBCMybatis数据库生命周期

时间轴&#xff1a; 32天主要学习内容&#xff1a; 1、JavaEE-HTTP-Servlet技术 2、JavaEE-数据库-JDBC&Mybatis java技术使用历史&#xff08;2023 &#xff09;&#xff1a; JavaEE-HTTP-Servlet&路由&周期: java学习范围&#xff1a; 3、Java: 功能:数据…

基于ZYNQ-7000系列的FPGA学习笔记7——按键控制蜂鸣器(模块化编写)

基于ZYNQ-7000系列的FPGA学习笔记7——按键控制蜂鸣器&#xff08;模块化编写&#xff09; 1. 实验要求2. 功能分析3. 模块设计4. 波形图4.1 按键消抖模块4.2 按键控制蜂鸣器模块 5.代码编写5.1 rtl代码5.2 测试代码 6. 代码仿真7. 添加约束文件并分析综合 在上期的内容中&…

k8s,声明式API对象理解

命令式API 比如&#xff1a; 先kubectl create&#xff0c;再replace的操作&#xff0c;我们称为命令式配置文件操作 kubectl replace的执行过程&#xff0c;是使用新的YAML文件中的API对象&#xff0c;替换原有的API对象&#xff1b;而kubectl apply&#xff0c;则是执行了一…

【金猿CIO展】复旦大学附属中山医院计算机网络中心副主任张俊钦:推进数据安全风险评估,防范化解数据安全风险,筑牢医疗数据安全防线...

‍ 张俊钦 本文由复旦大学附属中山医院计算机网络中心副主任张俊钦撰写并投递参与“数据猿年度金猿策划活动——2024大数据产业年度优秀CIO榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 数据要素时代&#xff0c;医疗数据已成为医院运营与决策的重要基石…

案例研究|HYPER PaaS低代码工具携手DataEase嵌入式版,服务工业制造企业数智化转型

杭州星瀚智磐科技有限公司&#xff08;以下简称为“星瀚智磐”&#xff09;成立于2021年&#xff0c;是一家专注于低代码平台研发的高科技企业。星瀚智磐的核心产品HYPER PaaS低代码工具主要为制造业用户提供数字化解决方案。HYPER PaaS基于低代码平台简单的拖拉拽操作&#xf…

2-2-18-13 QNX系统架构之原生网络(Qnet)

阅读前言 本文以QNX系统官方的文档英文原版资料为参考&#xff0c;翻译和逐句校对后&#xff0c;对QNX操作系统的相关概念进行了深度整理&#xff0c;旨在帮助想要了解QNX的读者及开发者可以快速阅读&#xff0c;而不必查看晦涩难懂的英文原文&#xff0c;这些文章将会作为一个…

Ubuntu系统上mysql服务部署

前段时间搞了一个mysql服务端的部署&#xff0c;在Ubuntu系统上&#xff0c;中间也踩了许多坑&#xff0c;特此记录下。 下载 官网&#xff1a;MySQL :: MySQL Community Downloads 这个里面有不同系统的安装包&#xff0c;根据自己的系统选择&#xff0c;我选了 MySQL Com…

IIC相关介绍及oled实验(二)

//模块&#xff1a;OLED显示屏 1. 0.96寸OLED屏幕介绍 0.96 寸 4P OLED 屏幕模块是一种显示屏模块&#xff0c;它包括一个 0.96 英寸的 OLED 显示屏和四个引脚。这种 OLED 屏幕模块通常用于嵌入式系统和小型电子设备中&#xff0c;可以显示文本、图像和其他类型的信息。由于其…

【工具变量】上市公司企业所在地城市等级直辖市、副省级城市、省会城市 计划单列市(2005-2022年)

一、包含指标&#xff1a; 股票代码 股票代码 股票简称 年份 所属城市 直辖市&#xff1a;企业所在地是否属于直辖市。1是&#xff0c;0否。 副省级城市&#xff1a;企业所在地是否属于副省级城市。1是&#xff0c;0否。 省会城市&a…