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

110、23种设计模式之状态模式(19/23)

一、定义

状态模式是一种行为型设计模式,它允许对象在内部状态改变时改变其行为,使得对象看起来好像修改了它的类。

核心思想:将对象的状态封装为独立的状态类,对象在不同状态下的行为由对应状态类实现,而非通过大量 if-else 或 switch 判断。

二、优缺点

优点:

  • 封装了状态的转换逻辑和不同状态下的行为,符合单一职责原则。

  • 避免了冗长的条件判断语句,代码可读性和可维护性更高。

  • 新增状态时只需扩展状态类,符合开闭原则。

  • 状态转换的逻辑清晰,便于跟踪和调试。

缺点:

  • 状态较多时,会导致状态类数量激增,增加系统复杂度。
  • 状态类之间可能存在依赖关系,增加了维护难度。

三、应用场景

  • 对象的行为依赖于其状态,且状态会频繁变化(如订单状态、支付状态)。
  • 代码中存在大量与状态相关的条件判断(if-else/switch),且难以维护。
  • 需要动态切换对象的行为,且不同行为之间有明确的状态边界(如游戏角色的 “存活”“受伤”“死亡” 状态)。

四、关键点总结

角色划分:

  • 环境类(Context):维护当前状态,负责状态切换,对外提供交互接口。
  • 抽象状态类(State):定义所有状态的公共行为接口。
  • 具体状态类(ConcreteState):实现抽象状态类,定义特定状态下的行为,并可触发状态转换。

核心逻辑

环境类通过委托当前状态对象处理请求,状态转换由具体状态类内部或环境类控制。

状态独立性

每个状态类专注于自身行为,降低耦合。

五、C# 代码示例

以 “订单状态流转” 为例,订单有 “待支付”“已支付”“已发货”“已完成” 四种状态,每种状态下的行为(如支付、发货、确认收货)不同。

using System;// 抽象状态类:定义订单状态的行为接口
public abstract class OrderState
{protected OrderContext context;// 设置环境类引用(用于状态切换)public void SetContext(OrderContext context){this.context = context;}// 抽象方法:支付订单public abstract void Pay();// 抽象方法:发货public abstract void Ship();// 抽象方法:确认收货public abstract void ConfirmReceipt();
}// 具体状态:待支付
public class PendingPaymentState : OrderState
{public override void Pay(){Console.WriteLine("订单已支付,状态更新为【已支付】");// 切换状态为“已支付”context.State = new PaidState();context.State.SetContext(context);}public override void Ship(){Console.WriteLine("错误:订单未支付,无法发货");}public override void ConfirmReceipt(){Console.WriteLine("错误:订单未支付,无法确认收货");}
}// 具体状态:已支付
public class PaidState : OrderState
{public override void Pay(){Console.WriteLine("错误:订单已支付,无需重复支付");}public override void Ship(){Console.WriteLine("订单已发货,状态更新为【已发货】");// 切换状态为“已发货”context.State = new ShippedState();context.State.SetContext(context);}public override void ConfirmReceipt(){Console.WriteLine("错误:订单未发货,无法确认收货");}
}// 具体状态:已发货
public class ShippedState : OrderState
{public override void Pay(){Console.WriteLine("错误:订单已支付,无需重复支付");}public override void Ship(){Console.WriteLine("错误:订单已发货,无需重复发货");}public override void ConfirmReceipt(){Console.WriteLine("订单已确认收货,状态更新为【已完成】");// 切换状态为“已完成”context.State = new CompletedState();context.State.SetContext(context);}
}// 具体状态:已完成
public class CompletedState : OrderState
{public override void Pay(){Console.WriteLine("错误:订单已完成,无需支付");}public override void Ship(){Console.WriteLine("错误:订单已完成,无需发货");}public override void ConfirmReceipt(){Console.WriteLine("错误:订单已完成,无需重复确认");}
}// 环境类:订单上下文,维护当前状态并提供交互接口
public class OrderContext
{private OrderState _state;// 初始状态为“待支付”public OrderContext(){_state = new PendingPaymentState();_state.SetContext(this);}// 当前状态(用于状态切换)public OrderState State{get => _state;set => _state = value;}// 委托当前状态处理支付public void PayOrder(){_state.Pay();}// 委托当前状态处理发货public void ShipOrder(){_state.Ship();}// 委托当前状态处理确认收货public void ConfirmOrder(){_state.ConfirmReceipt();}
}// 客户端调用
class Client
{static void Main(string[] args){OrderContext order = new OrderContext();// 模拟订单流程order.PayOrder();    // 订单已支付,状态更新为【已支付】order.ShipOrder();   // 订单已发货,状态更新为【已发货】order.ConfirmOrder();// 订单已确认收货,状态更新为【已完成】order.PayOrder();    // 错误:订单已完成,无需支付}
}

输出结果:

订单已支付,状态更新为【已支付】  
订单已发货,状态更新为【已发货】  
订单已确认收货,状态更新为【已完成】  
错误:订单已完成,无需支付  

说明:

  • 环境类 OrderContext 封装了订单状态的切换逻辑,客户端只需调用其公共方法(如 PayOrder)。
  • 每个具体状态类(如 PendingPaymentState)实现了对应状态下的行为,并在合适时机触发状态转换。
  • 新增状态(如 “已取消”)时,只需添加新的具体状态类,无需修改现有代码,符合开闭原则。

在这里插入图片描述

http://www.dtcms.com/a/564575.html

相关文章:

  • 做一手楼盘的网站嵌入式工程师能干多久
  • Spring Boot 应用 Docker 监控:Prometheus + Grafana 全方位监控
  • git clone失败
  • Linux 命令与运维终极手册(2025 完整版)
  • 05-异常处理-导读
  • Pandas-之 数据聚合与分组
  • Rust之基础入门项目实战:构建一个简单的猜谜游戏
  • 数据结构之二叉树-初见介绍
  • 【Java 开发日记】finally 释放的是什么资源?
  • VsCode中终端无法运行前端命令
  • 【鸿蒙开发】鸿蒙 ArkTS 语言从零到一完整指南
  • 门户网站建设公司网页设计风格分类
  • 综合整理:pdf预览显示:你尝试预览的文件可能对你的计算机有害。如果你信任此文件以及其来源,请打开此文件以看其内容,如何解决以正常预览文件
  • 微服务拆分之SpringCloud
  • Unity与iOS原生交互开发入门篇 - iOS原生弹窗与回调
  • 企业网站推广在哪里办成免费crm推广网站
  • 本地的赣州网站建设网站访问量asp
  • 总局核名的办理条件
  • 不只是计算:昇腾算子开发中的内存管理艺术
  • 深入解析 Spring Boot 自动配置:原理、实践与进阶​
  • 【Unity卷轴特效实现、原理、与深度解析】
  • STM32 串口中断接收原理与实战详解:从配置到中断服务函数全流程解析
  • 【Linux系统】C/C++的调试器gdb/cgdb,从入门到精通
  • 从被搜索到被推荐:GEO重塑可见性逻辑
  • 如何为 Oracle 数据库配置 TLS/TCPS
  • 阿里云网站备案注销吗大数据做网站
  • pc网站做app京东湖北网站推广服务
  • 测试环境与正式环境同样的机器显示不同的网络问题
  • HTTP_HTTPS协议
  • Linux高效备份:tar与gzip完全指南