包含大量if-else条件的CalculateSalary函数可维护性与可读性优化咨询
优化方案:规则模式重构多分支逻辑
针对当前多条件分支导致代码膨胀的问题,最适配的优化方案是使用规则设计模式,将每个条件分支拆分为独立的规则单元,后续新增规则只需要新增对应的规则类即可,不需要修改原有CalculateSalary的核心逻辑,完全符合开闭原则。
具体实现步骤
- 首先定义规则接口,统一规则的触发判断和执行逻辑入口
public interface ISalaryRule { // 判断当前SalaryDTO是否符合该规则的触发条件 bool IsMatch(SalaryDTO dto); // 符合条件时执行的处理逻辑 void Execute(SalaryDTO dto); }
- 把每个if分支的逻辑封装为独立的规则实现类,示例如下:
// 对应Salary>0且Bonus>0的规则 public class PositiveSalaryPositiveBonusRule : ISalaryRule { public bool IsMatch(SalaryDTO dto) { return dto.Salary > 0 && dto.Bonus > 0; } public void Execute(SalaryDTO dto) { dto.HRA = CalculateHRA(dto.Salary, dto.Bonus); dto.Allowance = CalculateAllowance(dto.Salary, dto.Bonus); dto.Output = "Profit"; } } // 对应Salary<0且Bonus<0的规则 public class NegativeSalaryNegativeBonusRule : ISalaryRule { public bool IsMatch(SalaryDTO dto) { return dto.Salary < 0 && dto.Bonus < 0; } public void Execute(SalaryDTO dto) { dto.HRA = CalculateHRA(dto.Salary, dto.Bonus); dto.Allowance = CalculateAllowance(dto.Salary, dto.Bonus); dto.Output = "Loss"; } } // 其余分支对应的规则类按照相同逻辑实现即可
- 重构CalculateSalary方法,只需要维护规则集合,遍历匹配执行即可:
public void CalculateSalary(List<SalaryDTO> salaryDTO) { // 初始化所有规则,顺序可按照业务优先级调整,和原有if判断顺序保持一致即可 var rules = new List<ISalaryRule> { new PositiveSalaryPositiveBonusRule(), new NegativeSalaryNegativeBonusRule(), // 新增规则仅需要在这里添加对应规则类的实例即可 }; foreach(var a in salaryDTO) { // 如果原有逻辑是匹配第一个满足的条件就停止,就用FirstOrDefault var matchedRule = rules.FirstOrDefault(r => r.IsMatch(a)); matchedRule?.Execute(a); // 如果原有逻辑允许多个满足的if都执行,就替换为以下逻辑: // foreach(var rule in rules.Where(r=>r.IsMatch(a))) // { // rule.Execute(a); // } } }
方案优势
- 完全消除了原方法里的大量if分支,核心逻辑清晰易读
- 新增规则不需要修改原有CalculateSalary的代码,只需要新增对应的规则类,再加入规则集合即可,避免代码持续膨胀
- 每个规则的逻辑独立,单测可以单独针对每个规则编写,维护成本更低
- 如果规则需要动态调整(比如调整优先级、开关某个规则),可以直接修改规则集合的初始化逻辑,不需要改动业务执行代码
轻量替代方案:委托字典(适合规则数量少且逻辑简单的场景)
如果不想定义太多类,也可以把条件和处理逻辑存到字典里实现轻量化改造:
public void CalculateSalary(List<SalaryDTO> salaryDTO) { var ruleMap = new Dictionary<Func<SalaryDTO, bool>, Action<SalaryDTO>> { {dto => dto.Salary>0 && dto.Bonus>0, dto => { dto.HRA = CalculateHRA(dto.Salary,dto.Bonus); dto.Allowance = CalculateAllowance(dto.Salary,dto.Bonus); dto.Output = "Profit"; }}, // 其余规则同理添加即可 }; foreach(var a in salaryDTO) { var matched = ruleMap.FirstOrDefault(kv => kv.Key(a)); matched.Value?.Invoke(a); } }
内容的提问来源于stack exchange,提问作者VA1267
相关产品推荐
相关产品推荐

