尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

使用场景规则匹配模式代替复杂的if else条件判断

使用场景规则匹配模式代替复杂的if else条件判断
📅 发布时间:2026/6/20 17:01:45

缘起

在业务处理程序中, 经常需要按照不同的场景有不同的处理方式, 在代码库中也充斥着大量的复杂的 if/else 语句, 这类代码可维护性非常差, 底层原因有:

  • 每个场景缺少定义,
  • 将场景识别和场景的应对代码耦合在一起。

解决方案

在代码中将场景明确化,将识别场景的条件与应对场景做隔离开来,

  • Scenario 类, 定义场景的基本信息, 比如场景名称、场景识别条件等。
  • ScenarioSelectionPolicyEnum 场景选择策略枚举, 比如选择高优先级场景, 还是低优先级场景, 还是返回所有符合条件的场景。
  • ISencarioRepository 接口:所有场景规则的存储库
  • ScenarioSelectionManager 类,按照场景选择策略, 将业务对象传入场景存储库中进行场景匹配。

示例代码

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Diagnostics.CodeAnalysis;class Test
{public static void Main(){ISencarioRepository ruleRepository = new BookDiscountRuleRepository();var bizRuleSelectionManager = new ScenarioSelectionManager(ruleRepository, ScenarioSelectionPolicyEnum.HighestPriorty);Book book1 = new Book(){Name = "book1",Category = "category1",PressHouse = "zhongxin",Price = 100};Book book2 = new Book(){Name = "book2",Category = "book2",PressHouse = "xxx",Price = 5};string traceMessage1;List<Scenario> selectedScenarioList1 = bizRuleSelectionManager.Select(book1, out traceMessage1);Console.WriteLine(book1.Name);Console.WriteLine(traceMessage1);}
}/// <summary>
/// 场景定义类
/// </summary>
public class Scenario
{/// <summary>/// 场景名, 要求唯一/// </summary>/// <value></value>public string Name { get; set; }/// <summary>/// 该场景是否被启用/// </summary>/// <value></value>public bool Enabled { get; set; } = true;/// <summary>/// 是否是默认场景/// </summary>/// <value></value>public bool IsDefault { get; set; } = false;/// <summary>/// 场景优先级/// </summary>/// <value></value>public int Priority { get; set; }/// <summary>/// 场景识别条件/// 函数传入一个业务对象, 返回值为boolean型,如果符合该场景则返回true/// </summary>/// <value></value>public Func<object, bool> Condition { get; set; } = null;/// <summary>/// 场景规则可以附带的信息, 比如针对打折场景, 可以附上折扣/// </summary>/// <value></value>public object Payload { get; set; } = null;public override string ToString(){return $"Name:{Name}";}}/// <summary>
/// 场景选择策略
/// </summary>
public enum ScenarioSelectionPolicyEnum
{AllMatched,HighestPriorty,LowestPriority,HighestPriortyOrDefault,LowestPriorityOrDefault,
}/// <summary>
/// 定义场景规则库的接口
/// </summary>
public interface ISencarioRepository
{public List<Scenario> BuildScenarioRepository();
}/// <summary>
/// 场景选择控制器
/// </summary>
public class ScenarioSelectionManager
{ScenarioSelectionPolicyEnum _policy;ISencarioRepository _scenarioRepository;List<Scenario> _scenarioList;private void CheckScenarioRepository(ScenarioSelectionPolicyEnum policy){//TODO://检查是否有同名的场景//检查是否有优先级相等的场景}private List<Scenario> SortScenarioList(){//TODO: 排序return _scenarioRepository.BuildScenarioRepository();}public ScenarioSelectionManager(ISencarioRepository scenarioRepository, ScenarioSelectionPolicyEnum policy){_scenarioRepository = scenarioRepository;_policy = policy;CheckScenarioRepository(policy);_scenarioList = SortScenarioList();}/// <summary>/// 按照策略来选择匹配的场景, 支持匹配多个场景以满足场景叠加需求/// </summary>/// <param name="bizObject"></param>/// <param name="traceMessage"></param>/// <returns></returns>public List<Scenario> Select(object bizObject, out string traceMessage){//TODO: 待完善traceMessage = "";List<String> notMatchedMsgList = new List<string>();var selectedScenarioList = new List<Scenario>();foreach (Scenario scenario in _scenarioList){if (scenario.Enabled == false){notMatchedMsgList.Add($"{scenario} disabled");}else if (scenario.Condition(bizObject)){selectedScenarioList.Add(scenario);}else{notMatchedMsgList.Add($"{scenario} not matched");}}var matchedStr = "";if (selectedScenarioList.Count != 0){matchedStr = string.Join(",", selectedScenarioList);matchedStr = $"Matched scenarios:{matchedStr}";}else{matchedStr = "No matched scenario";}var notMatchedStr = string.Join(",", notMatchedMsgList);notMatchedStr = $"Not matched scenarios:{notMatchedStr}";traceMessage = matchedStr + ", " + notMatchedStr;return selectedScenarioList;}
}/// <summary>
/// 图书类, 即业务对象类
/// </summary>
class Book
{public string Name { get; set; }public double Price { get; set; }public string PressHouse { get; set; }public string Category { get; set; }
}/// <summary>
/// 图书打折场景类, 即针对业务对象的场景规则库
/// </summary>
class BookDiscountRuleRepository : ISencarioRepository
{public List<Scenario> BuildScenarioRepository(){List<Scenario> lst = new();//场景1: 高价图书Scenario highPriceScenario = new Scenario(){Name = nameof(highPriceScenario),Enabled = true,Priority = 10,IsDefault = false,Condition = (obj) => (obj as Book).Price > 100,Payload = 0.5};lst.Add(highPriceScenario);//中信出版的图书Scenario ZhongxinPressScenario = new Scenario(){Name = nameof(ZhongxinPressScenario),Enabled = true,Priority = 10,IsDefault = false,Condition = (obj) => (obj as Book).PressHouse.ToUpper() == "ZHONGXIN",Payload = 0.6};lst.Add(ZhongxinPressScenario);//普调图书Scenario SunShineScenario = new Scenario(){Name = nameof(SunShineScenario),Enabled = true,Priority = 10,IsDefault = true,Condition = (object obj) =>{return true;},Payload = 0.9};lst.Add(SunShineScenario);return lst;}
}

相关新闻

  • 【操作系统】函数调用
  • ABC425
  • 维生素D,毛姆,我,还有停滞的3年

最新新闻

  • Express.js终极实战指南:从零构建企业级Web应用
  • 嵌入式GUI显示驱动配置实战:从emWin框架到自定义驱动开发
  • YOLOv8轻量微调方案:C2PSA注意力与Mona认知适配器集成
  • 照片清晰度不够,用这个方法无损提升细节 - 软件工具教程方法
  • 海南怎么登报挂失?2026最新流程避坑指南 - 资讯速览
  • 2026南宁奢侈品回收行业白皮书:出手名贵腕表怕信息泄露,私密交易一对一全程保护隐私 - 讯息早知道

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号