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

C#设计模式(行为型模式):状态模式

C#设计模式:状态模式

在软件开发中,我们经常会遇到对象的行为取决于其状态的情况。例如,一个订单对象可能处于“待支付”、“已支付”、“已发货”等不同状态,而每个状态下订单的行为(例如是否可以支付、是否可以发货)是不同的。

传统的处理方式是使用大量的 if-elseswitch-case 语句来判断对象的状态,然后执行相应的行为。这种方式虽然直观,但随着状态数量的增加,代码会变得臃肿、难以维护,并且违背了开放-封闭原则。

状态模式 (State Pattern) 提供了一种优雅的解决方案,它将对象的状态抽象成独立的类,并将对象的行为委托给当前状态对象。这样,对象就可以在不同的状态下表现出不同的行为,而无需修改自身的代码。

一、状态模式的结构

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

  • Context(上下文): 定义客户感兴趣的接口,并维护一个具体状态对象的实例,该实例定义了对象的当前状态。
  • State(状态): 定义一个接口,用于封装与 Context 的特定状态相关的行为。
  • ConcreteState(具体状态): 实现 State 接口,每个具体状态类对应对象的一种状态,并实现该状态下的行为。

二、状态模式的实现

以下是一个简单的 C# 示例,演示如何使用状态模式实现一个订单系统:

// Context 类
public class Order
{
    private OrderState _state;

    public Order()
    {
        // 初始状态为待支付
        _state = new PendingPaymentState(this);
    }

    public void SetState(OrderState state)
    {
        _state = state;
    }

    public void Pay()
    {
        _state.Pay();
    }

    public void Ship()
    {
        _state.Ship();
    }

    public void Cancel()
    {
        _state.Cancel();
    }
}

// State 接口
public interface OrderState
{
    void Pay();
    void Ship();
    void Cancel();
}

// 具体状态类:待支付
public class PendingPaymentState : OrderState
{
    private Order _order;

    public PendingPaymentState(Order order)
    {
        _order = order;
    }

    public void Pay()
    {
        Console.WriteLine("订单支付成功!");
        _order.SetState(new PaidState(_order));
    }

    public void Ship()
    {
        Console.WriteLine("订单未支付,无法发货!");
    }

    public void Cancel()
    {
        Console.WriteLine("订单已取消!");
        _order.SetState(new CancelledState(_order));
    }
}

// 具体状态类:已支付
public class PaidState : OrderState
{
    private Order _order;

    public PaidState(Order order)
    {
        _order = order;
    }

    public void Pay()
    {
        Console.WriteLine("订单已支付,无需重复支付!");
    }

    public void Ship()
    {
        Console.WriteLine("订单发货成功!");
        _order.SetState(new ShippedState(_order));
    }

    public void Cancel()
    {
        Console.WriteLine("订单已支付,无法取消!");
    }
}

// 具体状态类:已发货
public class ShippedState : OrderState
{
    private Order _order;

    public ShippedState(Order order)
    {
        _order = order;
    }

    public void Pay()
    {
        Console.WriteLine("订单已发货,无法支付!");
    }

    public void Ship()
    {
        Console.WriteLine("订单已发货,无需重复发货!");
    }

    public void Cancel()
    {
        Console.WriteLine("订单已发货,无法取消!");
    }
}

// 具体状态类:已取消
public class CancelledState : OrderState
{
    private Order _order;

    public CancelledState(Order order)
    {
        _order = order;
    }

    public void Pay()
    {
        Console.WriteLine("订单已取消,无法支付!");
    }

    public void Ship()
    {
        Console.WriteLine("订单已取消,无法发货!");
    }

    public void Cancel()
    {
        Console.WriteLine("订单已取消,无需重复取消!");
    }
}

// 客户端代码
class Program
{
    static void Main(string[] args)
    {
        Order order = new Order();

        order.Pay();   // 输出:订单支付成功!
        order.Ship();  // 输出:订单发货成功!
        order.Cancel(); // 输出:订单已发货,无法取消!
    }
}

三、状态模式的优点

  • 将状态相关的行为局部化: 将与特定状态相关的行为封装在独立的类中,使得代码更加清晰、易于理解和维护。
  • 避免使用大量的条件语句: 通过将状态转换逻辑分散到各个状态类中,可以避免使用大量的 if-elseswitch-case 语句,提高代码的可读性和可维护性。
  • 方便添加新的状态: 如果需要添加新的状态,只需要创建新的具体状态类,并实现相应的行为即可,无需修改现有的代码,符合开放-封闭原则。

四、状态模式的适用场景

  • 对象的行为取决于其状态,并且状态数量较多。
  • 需要在运行时根据状态改变对象的行为。
  • 需要避免使用大量的条件语句来判断对象的状态。

五、总结

状态模式是一种非常有用的设计模式,它可以帮助我们更好地组织和管理对象的状态和行为。通过将状态抽象成独立的类,并将行为委托给当前状态对象,我们可以使代码更加清晰、易于理解和维护。


http://www.kler.cn/a/468676.html

相关文章:

  • 自动采集商品信息、处理数据并自动上架到
  • 【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习(L14+L15+L16)
  • 【C++项目实战】类和对象入门实践:日期类实现万字详解
  • 基于开发/发布/缺陷分离模型的 Git 分支管理实践20250103
  • 【sql】CAST(GROUP_CONCAT())实现一对多对象json输出
  • Level DB --- BloomFilterPolicy
  • web实操9——session
  • 基于傅立叶神经网络(FNN)与物理信息神经网络(PINN)求解泊松方程(附Pytorch源代码)
  • 高等数学学习笔记 ☞ 连续与间断
  • weblogic安装 12.2.1.4.0 单机
  • 工程师了解的Lua语言
  • Python 使用会话 ID 管理多轮对话
  • web应用安全评估报告:会话Cookie未设置Secure属性(如果网站未部署 HTTPS,则无法使用 Secure 属性。)
  • 计算机网络--路由表的更新
  • Verilog语法之模块与端口
  • 基于LightGBM的集成学习算法
  • sniff2sipp: 把 pcap 处理成 sipp.xml
  • 深入探讨服务器虚拟化:架构、技术与应用
  • 在 macOS 中,设置自动将文件夹排在最前
  • 小程序组件 —— 28 组件案例 - 推荐商品区域 - 实现结构样式
  • React 如何进行路由变化监听
  • qt-C++笔记之动画框架(Qt Animation Framework)入门
  • 【Unity报错】error Cs0103: The name ‘keyCode‘ does not exist in the current context
  • 《机器学习》——决策树
  • 【Leetcode 每日一题】2241. 设计一个 ATM 机器
  • 12.3【hardware][day3]