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

news/2025/9/28 6:58:32/文章来源:https://www.cnblogs.com/harrychinese/p/19115991

缘起

在业务处理程序中, 经常需要按照不同的场景有不同的处理方式, 在代码库中也充斥着大量的复杂的 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;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920301.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9.28作业

结果: false false true SMALL MEDIUM 原因:枚举是特殊的类,他的每一个枚举值都是类的实例,LARGE两者指向不同内存地址,因此结果为 false 。isPrimitive() 用于判断是否为原始类型,因此结果为 false 。 结论:…

网站举报能不能查到举报人网站建设合同 模板

环境:win7python2.7 一直想学习多进程或多线程,但之前只是单纯看一点基础知识还有简单的介绍,无法理解怎么去应用,直到前段时间看了github的一个爬虫项目涉及到多进程,多线程相关内容,一边看一边百度相关知识点,现在把一些相关知识点和一些应用写下来做个记录. 首先说下什么是进…

广东网站建设英铭科技开一个小程序要多少钱

1.使用YUM查找软件包 $ yum search python 2.列出所有可安装的软件包 $ yum list | grep python 3.列出所有可更新的软件包 $ yum list updates 4.列出所有已安装的软件包 $ yum list installed | grep python

哪个网站可以搭建网页网站建设合同 技术合同

城市的街道因为汽车数量的增长越来越繁忙&#xff0c;对于驾车一族而言&#xff0c;在热门区域寻找停车场更是无比头痛的事情。然而与此同时&#xff0c;其实也许很多办公楼、住宅楼、酒店和公共车库中仍有许多付费停车的资源未被充分利用。 ParkBee就是这样一家为城市提供智能…

上海校园兼职网站建设微信插件 wordpress

数字人是指通过人工智能和虚拟形象技术创造的虚拟个体&#xff0c;具备自己的外貌、声音和行为。数字人的出现引起了广泛关注和热议&#xff0c;成为当今社会热门话题。本文将解析数字人的概念和特点&#xff0c;并探讨数字人之所以如此火爆的原因。 一、什么是数字人&#xf…

链接网站某一页面如何做自己怎么做网站推广

VS2022今天Visual Studio 2022 终于发布了&#xff0c;你只需要按下⾯地址就可以快速安装你所需要的Visual Studio 2022版本&#xff0c;包括了企业版本&#xff0c;专业版本&#xff0c;以及社区版本。请输入以下⽹址安装最新的Visual Studio 2022 https://aka.ms/InstallVS或…

2025.9.28+7[未完]

2025.9.28 Week 笔记2025.9.28

网站备案ip更换企业网站ui设计

1. 卷积神经网络结构&#xff1a;分为输入层&#xff0c;卷积层&#xff0c;池化层&#xff0c;全连接层&#xff1b; &#xff08;1&#xff09;首先进入输入层&#xff0c;对数据数据进行处理&#xff0c;将输入数据向量化处理&#xff0c;最终形成输入矩阵。 &#xff08;…

建设网站一定要电脑吗网站建设背景介绍

ORI-S3R500 -多路PCIe3.0的单CPU通用工作站 (研华工业计算机IPC-610&#xff0c;IPC940 升级款) 一、机箱功能和技术指标&#xff1a; 系统 系统型号 ORI-SR500 主板支持 EEB(12*13)/CEB(12*10.5)/ATX(12*9.6)/Mi cro ATX 前置硬盘 最大支持2个3.5寸1个2.5寸SATA …

网站建设的发展趋势网站网站代理怎么做的

远程控制网关在工厂自动化领域中起到了至关重要的作用&#xff0c;特别是在工厂PLC数据通讯方面。它充当着数据传输的桥梁&#xff0c;连接了工厂中的各类设备和系统&#xff0c;实现了远程监控和控制的功能。本文将详细介绍远程控制网关在工厂PLC数据通讯中的应用。 远程控制网…

做家常菜的网站哪个好广东新闻联播今天

博主是将大图切分成小图时遇到 问题一、linux编译后&#xff0c;找不到ffmpeg中的一个文件 产生原因&#xff0c;各种包集成&#xff0c;然后安装以后乱七八糟&#xff0c;甚至官方的教程也不规范导致没有添加路径到系统文件导致系统执行的时候找不到 1.下载 博主进行的离线…

做外贸生意最好的网站使用html制作个人主页

一 Vue3的变化 1.性能的提升 打包大小减少41% 初次渲染快55%, 更新渲染快133% 内存减少54% 2.源码的升级 使用Proxy代替defineProperty实现响应式 重写虚拟DOM的实现和Tree-Shaking 3.拥抱TypeScript Vue3可以更好的支持TypeScript 4.新的特性 Composition API&#…

网站维护公司推荐建网站和建小程序多少钱

uboot启动流程分析如下&#xff1a; 第一阶段&#xff1a; a -- 设置cpu工作模式为SVC模式 b -- 关闭中断&#xff0c;mmu,cache v -- 关看门狗 d -- 初始化内存&#xff0c;串口 e -- 设置栈 f -- 代码自搬移 g -- 清bss h -- 跳c 第二阶段 a -- 初始化外设&#xff0c;进入超…

只会后端不会前端如何做网站郑州的网站公司哪家好

实验报告记录 得到实验结果 转载于:https://www.cnblogs.com/ma1998/p/11536959.html

无需登录即可在管理员页面发现XSS漏洞的技术解析

本文详细介绍了作者如何通过参数模糊测试技术在管理员登录页面发现XSS漏洞的全过程。从目标侦察到参数发现,再到漏洞利用,完整展现了白帽黑客的漏洞挖掘思路和方法,重点展示了Arjun工具在发现隐藏参数过程中的关键作…

网站后期维护是做什么如何做好网站seo

mysql开启远程连接 今天在服务器安装了mysql&#xff0c;准备用mysqlguitools远程登录的时候出错&#xff0c;提示&#xff1a;Host xxx is not allowed to connect to this MySQL server。网上找了一些资料&#xff0c;是mysql未开启mysql远程访问权限导致。 记录解决方案供以…

企业网站要怎么做win7建设网站教程

W外链地址wai.cn 在数字化时代的浪潮中&#xff0c;私域流量的价值愈发凸显&#xff0c;成为企业获取用户、建立品牌忠诚度、提升转化率的关键手段。抖音&#xff0c;作为当下最热门的短视频社交平台之一&#xff0c;其用户基数庞大、互动性强&#xff0c;为企业私域引流提供了…

人网站设计与制作做网站哪家南京做网站

Linux C 027-STL之deque容器 本节关键字&#xff1a;Linux、C、deque 相关库函数&#xff1a;pubsh_back、begin、front、sort deque基本概念 功能&#xff1a;双端数组&#xff0c;可以对头端进行插入删除操作。 deque 与 vector 的区别&#xff1a; &#xff08;1&#x…

微网站开发需求房产信息网 源码

随着互联网时代的飞速发展&#xff0c;越来越多的人投身于软件开发行业&#xff0c;大家都称他们为程序员&#xff0c;或者码农。 这些程序员的水平也是参差不齐的&#xff0c;有些人从比较好的学校毕业&#xff0c;水平却一般般&#xff1b;也有些人从一般搬的学校毕业&#…

优秀网站 要素同一ip网站

组网需求 如图1所示&#xff0c;企业网内部LAN侧的语音、视频和数据业务通过Switch连接到RouterA的Eth2/0/0上&#xff0c;并通过RouterA的GE3/0/0连接到WAN侧网络。 不同业务的报文在LAN侧使用802.1p优先级进行标识&#xff0c;在RouterA上根据报文的802.1p优先级入队列&…