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

如何优化含SubRequest的Request类多状态管理设计?

问题描述

现有一个Request类,包含多种状态,且可关联多个SubRequest,SubRequest的状态变更会同步到Request。当前实现如下:

Request {
 public MyState SignatureState{get; set;}
 public MyState CheckedState{get; set;}
 public MyState ConfirmedState{get; set;}
 ....20 more
 
 public ICollection<SubRequest>? subs {get; set;}
}

SubRequest {
    public MyState SignatureState{get; set;}
     public MyState CheckedState{get; set;}
     public MyState ConfirmedState{get; set;}
     ....20 more    
}

SubRequest可在Request创建时或运行中添加,当SubRequest状态变更时,Request状态需同步更新。当前在Logic类中通过大量if语句处理状态检查和变更,状态由用户设置,且需前一个状态为Confirmed才能修改下一个状态。此外,存在LoanRequest、StateAidRequest等Request子类,它们不需要全部状态,目前通过switch语句在创建时将不需要的状态设为Not_Needed。现有实现繁琐冗余,曾考虑状态模式但觉得不适用,寻求更优设计方案。

补充Logic类代码:

public class Logic{
 public updateState(Request req){
  if(req.SignatureState==DONE) req.ChekedState=NEXT;    
  if(req.CheckedState==DONE) req.ConfirmedState=NEXT;
  ....
  if(req.LastState==DONE) req.CompletelyDone = true;
 }
 
 public StateChanged(Request req){
   req.CompletelyDone=false;
 }

 public resetStates(Request req){
   req.SignatureState=NEXT;
   req.CheckedState = TO_BE_DONE;
   .....
 }
}

UI/Controller会检查状态是否为NEXT,若是则允许用户修改,否则锁定。每次SubRequest状态变更时都会调用updateStates方法。


优化方案

1. 用状态组+枚举替代零散状态属性

把一组关联的状态抽象成ProcessStage枚举,每个枚举项对应一个流程阶段(比如Signature、Checked、Confirmed等),然后用字典存储每个阶段的状态,替换20多个重复的属性,同时方便扩展:

public enum ProcessStage
{
    Signature,
    Checked,
    Confirmed,
    // 其他阶段
}

public class RequestBase
{
    public Dictionary<ProcessStage, MyState> StageStates { get; set; } = new();
    public ICollection<SubRequest>? Subs { get; set; }
    public bool CompletelyDone => StageStates.Values.All(s => s == MyState.DONE);
}

public class SubRequest
{
    public Dictionary<ProcessStage, MyState> StageStates { get; set; } = new();
}

对于不同的Request子类(如LoanRequest),只需在构造时初始化自身需要的ProcessStage,无需设置Not_Needed:

public class LoanRequest : RequestBase
{
    public LoanRequest()
    {
        StageStates.Add(ProcessStage.Signature, MyState.TO_BE_DONE);
        StageStates.Add(ProcessStage.Checked, MyState.TO_BE_DONE);
        // 只添加需要的阶段
    }
}

2. 用规则引擎处理状态流转逻辑

把状态流转规则(比如“前一个阶段为DONE时,下一个阶段设为NEXT”)抽象成可配置的规则集合,替换Logic类中大量的if语句:

public class StateTransitionRule
{
    public ProcessStage PreviousStage { get; set; }
    public ProcessStage NextStage { get; set; }
    public MyState TriggerState { get; set; } = MyState.DONE;
    public MyState TargetState { get; set; } = MyState.NEXT;
}

在Logic类中维护规则列表,通过遍历规则处理状态更新:

public class Logic
{
    private readonly List<StateTransitionRule> _transitionRules = new()
    {
        new StateTransitionRule { PreviousStage = ProcessStage.Signature, NextStage = ProcessStage.Checked },
        new StateTransitionRule { PreviousStage = ProcessStage.Checked, NextStage = ProcessStage.Confirmed },
        // 其他流转规则
    };

    public void UpdateState(RequestBase req)
    {
        foreach (var rule in _transitionRules)
        {
            if (req.StageStates.TryGetValue(rule.PreviousStage, out var prevState) 
                && prevState == rule.TriggerState
                && req.StageStates.TryGetValue(rule.NextStage, out _))
            {
                req.StageStates[rule.NextStage] = rule.TargetState;
            }
        }
    }

    public void StateChanged(RequestBase req)
    {
        req.CompletelyDone = false;
    }

    public void ResetStates(RequestBase req)
    {
        foreach (var stage in req.StageStates.Keys)
        {
            req.StageStates[stage] = stage == ProcessStage.Signature ? MyState.NEXT : MyState.TO_BE_DONE;
        }
    }
}

新增状态流转时只需添加规则,无需修改大量if语句,不同Request子类也可以有独立的规则集合。

3. 让SubRequest状态变更自动同步到Request

给SubRequest添加状态变更事件,当状态改变时触发事件,Request订阅事件并自动更新自身状态,避免手动调用updateStates:

public class SubRequest
{
    public event Action<ProcessStage, MyState> StageStateChanged;

    private Dictionary<ProcessStage, MyState> _stageStates = new();
    public Dictionary<ProcessStage, MyState> StageStates => _stageStates;

    // 单个状态设置方法,触发事件
    public void SetStageState(ProcessStage stage, MyState state)
    {
        _stageStates[stage] = state;
        StageStateChanged?.Invoke(stage, state);
    }
}

在Request中订阅每个SubRequest的事件:

public class RequestBase
{
    public void AddSubRequest(SubRequest sub)
    {
        Subs ??= new List<SubRequest>();
        Subs.Add(sub);
        sub.StageStateChanged += OnSubStageStateChanged;
    }

    private void OnSubStageStateChanged(ProcessStage stage, MyState state)
    {
        // 示例逻辑:所有SubRequest该阶段都完成时,Request对应阶段设为完成
        if (Subs.All(s => s.StageStates.TryGetValue(stage, out var sState) && sState == MyState.DONE))
        {
            StageStates[stage] = MyState.DONE;
            new Logic().UpdateState(this);
        }
    }
}

4. 用策略模式处理不同Request子类的状态逻辑

如果不同Request子类的状态流转规则差异较大,为每个子类定义对应的状态策略,解耦子类与状态逻辑:

public interface IRequestStateStrategy
{
    void InitializeStates(RequestBase request);
    void UpdateStates(RequestBase request);
}

public class LoanRequestStateStrategy : IRequestStateStrategy
{
    public void InitializeStates(RequestBase request)
    {
        request.StageStates.Add(ProcessStage.Signature, MyState.NEXT);
        request.StageStates.Add(ProcessStage.Checked, MyState.TO_BE_DONE);
        // 贷款请求专属初始化逻辑
    }

    public void UpdateStates(RequestBase request)
    {
        // 贷款请求专属状态流转逻辑
    }
}

public class StateAidRequestStateStrategy : IRequestStateStrategy
{
    // 救助请求专属逻辑
}

在Request子类构造时注入对应的策略:

public class LoanRequest : RequestBase
{
    public LoanRequest(IRequestStateStrategy strategy)
    {
        strategy.InitializeStates(this);
    }
}

新增子类只需添加对应的策略类,无需修改现有代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:30:49