You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#状态模式示例疑问:委托作用、账户初始化及状态判断

状态设计模式(C#)相关疑问解答

我来帮你理清这几个关于状态模式实现的疑问,结合你提供的C#代码逐一说明:

问题1:为什么具体状态类和上下文类要使用Action委托?

首先,这里的委托核心作用是解耦状态类与上下文类(Account)的依赖关系。如果直接让状态类持有Account的引用,状态类会和Account的具体实现绑定死——比如以后Account修改了属性或方法,状态类大概率也要跟着调整。

用Action委托的话,状态类完全不需要知道Account的内部细节,只需要明确“要执行某个操作”:

  • 比如Deposit方法里的addToBalance委托,只是告诉状态类“执行这个委托就能完成余额增加”,状态类不用关心余额存在Account的哪个属性里;
  • 而OnUnfreeze委托是给冻结状态(你的示例代码里没贴Frozen类,但从Active的Freeze方法能推断出这个类的存在)准备的:当账户从冻结状态恢复到活跃状态时,触发这个委托执行特定逻辑(比如通知用户、记录操作日志),状态类不需要直接调用Account的方法,只需要执行委托即可。

这种方式完全符合依赖倒置原则——状态类依赖抽象(委托代表的操作),而非具体的Account类,让代码更灵活、更容易扩展。

问题2:如何正确初始化Account实例(初始状态为NotVerified)?

你尝试的代码Action initialState = () => { }; Account account= new Account(initialState);语法上是正确的,但需要明确构造函数参数的意义:这个Action是onUnfreeze(解冻回调),而非“初始状态”。

Account的构造函数已经默认把初始状态设置为NotVerified了(看代码里this.State = new NotVerified(onUnfreeze);),所以你只需要根据需求传入解冻时的回调即可:

  • 如果不需要解冻时的额外操作,直接传空委托:
    Account account = new Account(() => { });
    
  • 如果需要在解冻时执行特定逻辑(比如打印提示日志):
    Account account = new Account(() => Console.WriteLine("账户已完成解冻"));
    

问题3:如何判断Account当前的状态?

因为Account里的State属性是private的,外部无法直接访问。你可以通过两种方式来暴露当前状态:

方式1:添加公开属性获取状态类型名

在Account类里添加一个只读属性,返回当前状态的类型名称:

class Account
{
    // ... 原有代码 ...
    public string CurrentStateName => State.GetType().Name;
}

使用时直接读取account.CurrentStateName,就能得到类似"NotVerified"、"Active"、"Closed"这样的状态名称。

方式2:给状态接口添加强类型状态标识

更优雅的方式是给IAccountState接口添加一个属性,结合枚举实现强类型的状态标识:

// 先定义状态枚举
public enum AccountStateType
{
    NotVerified,
    Active,
    Frozen,
    Closed
}

// 修改状态接口
interface IAccountState
{
    AccountStateType StateType { get; }
    // ... 原有方法 ...
}

// 每个具体状态类实现这个属性
class NotVerified : IAccountState
{
    public AccountStateType StateType => AccountStateType.NotVerified;
    // ... 原有代码 ...
}

class Active : IAccountState
{
    public AccountStateType StateType => AccountStateType.Active;
    // ... 原有代码 ...
}

// 最后在Account类里添加公开属性
class Account
{
    // ... 原有代码 ...
    public AccountStateType CurrentState => State.StateType;
}

这种方式类型更安全,避免了字符串比较的潜在问题,也更符合面向对象的设计思路。


内容的提问来源于stack exchange,提问作者Eseosa Omoregie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:47:53