当前位置:首页 > C# > 正文

C#状态模式详解(从零开始掌握状态模式在C#中的应用)

在软件开发中,我们经常会遇到对象的行为会随着其内部状态的改变而变化。如果用大量的 if-else 或 switch 语句来处理这些状态转换,代码会变得难以维护和扩展。这时,C#状态模式就派上用场了!

C#状态模式详解(从零开始掌握状态模式在C#中的应用) C#状态模式 状态模式教程 C#设计模式 状态模式实现 第1张

什么是状态模式?

状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

简单来说,状态模式将每个状态封装成一个独立的类,并将与该状态相关的行为放在对应的类中。这样,当状态改变时,只需切换到另一个状态对象即可,而无需修改原有代码。

为什么使用状态模式?

  • 避免庞大的条件判断语句(如 if-else、switch)
  • 提高代码的可读性和可维护性
  • 符合“开闭原则”:新增状态无需修改现有代码
  • 使状态转换逻辑清晰、集中

C#状态模式实战示例:自动售货机

我们以一个简单的自动售货机为例,它有三种状态:

  • 无硬币状态(NoCoinState):不能出货,只能投币
  • 有硬币状态(HasCoinState):可以退币或按出货按钮
  • 售出状态(SoldState):正在出货,完成后回到无硬币状态

第一步:定义状态接口

public interface IVendingMachineState{    void InsertCoin();    void EjectCoin();    void PressButton();    void Dispense();}

第二步:实现具体状态类

1. 无硬币状态

public class NoCoinState : IVendingMachineState{    private VendingMachine machine;    public NoCoinState(VendingMachine machine)    {        this.machine = machine;    }    public void InsertCoin()    {        Console.WriteLine("硬币已投入。");        machine.SetState(machine.HasCoinState);    }    public void EjectCoin()    {        Console.WriteLine("没有硬币可退。");    }    public void PressButton()    {        Console.WriteLine("请先投入硬币。");    }    public void Dispense()    {        Console.WriteLine("请先按出货按钮。");    }}

2. 有硬币状态

public class HasCoinState : IVendingMachineState{    private VendingMachine machine;    public HasCoinState(VendingMachine machine)    {        this.machine = machine;    }    public void InsertCoin()    {        Console.WriteLine("已有硬币,请勿重复投入。");    }    public void EjectCoin()    {        Console.WriteLine("硬币已退还。");        machine.SetState(machine.NoCoinState);    }    public void PressButton()    {        Console.WriteLine("出货中...");        machine.SetState(machine.SoldState);    }    public void Dispense()    {        // 此状态下不直接调用 Dispense        Console.WriteLine("请先按出货按钮。");    }}

3. 售出状态

public class SoldState : IVendingMachineState{    private VendingMachine machine;    public SoldState(VendingMachine machine)    {        this.machine = machine;    }    public void InsertCoin()    {        Console.WriteLine("正在出货,请稍后再投币。");    }    public void EjectCoin()    {        Console.WriteLine("已按下出货按钮,无法退币。");    }    public void PressButton()    {        Console.WriteLine("已处理出货请求,请勿重复操作。");    }    public void Dispense()    {        Console.WriteLine("商品已出货!");        machine.SetState(machine.NoCoinState);    }}

第三步:创建上下文类(VendingMachine)

public class VendingMachine{    public IVendingMachineState NoCoinState { get; }    public IVendingMachineState HasCoinState { get; }    public IVendingMachineState SoldState { get; }    private IVendingMachineState currentState;    public VendingMachine()    {        NoCoinState = new NoCoinState(this);        HasCoinState = new HasCoinState(this);        SoldState = new SoldState(this);        currentState = NoCoinState; // 初始状态    }    public void SetState(IVendingMachineState state)    {        currentState = state;    }    public void InsertCoin() => currentState.InsertCoin();    public void EjectCoin() => currentState.EjectCoin();    public void PressButton() => currentState.PressButton();    public void Dispense() => currentState.Dispense();}

第四步:测试我们的状态模式

class Program{    static void Main(string[] args)    {        var vendingMachine = new VendingMachine();        vendingMachine.PressButton();      // 请先投入硬币。        vendingMachine.InsertCoin();       // 硬币已投入。        vendingMachine.InsertCoin();       // 已有硬币,请勿重复投入。        vendingMachine.PressButton();      // 出货中...        vendingMachine.Dispense();         // 商品已出货!        vendingMachine.EjectCoin();        // 没有硬币可退。    }}

状态模式的优点与适用场景

通过上面的例子,我们可以看到 C#设计模式 中的状态模式让代码结构更清晰。以下是它的主要优点:

  • 消除大量条件分支语句
  • 每个状态的行为独立,便于单元测试
  • 新增状态只需添加新类,不修改现有逻辑(符合开闭原则)

适用于以下场景:

  • 对象行为依赖于其状态,且状态较多
  • 状态转换规则复杂
  • 需要频繁增加新状态

总结

本文详细介绍了 状态模式教程,并通过一个完整的 C# 示例展示了如何实现 状态模式实现。对于初学者来说,理解状态模式不仅能提升代码质量,还能为学习其他设计模式打下基础。

记住:好的设计不是写更多代码,而是让代码更聪明地工作。状态模式正是这样一种“聪明”的解决方案。