还在写大量 if 来判断?试试用一个规则执行器来替代它

C# If 判断泛滥?试试规则执行器,太香了! 为了解决if条件判断泛滥的问题,我们可以引入规则执行器(Rule Engine)。规则执行器可以帮助我们定义、管理和执行复杂的业务规则,而无需编写大量的if-else语句。通过上面的例子,我们看到了如何使用规则执行器来简化if条件判断的代码。规则执行器不仅让代码更易于阅读和维护,还能方便地扩展新的规则。好啦,今天的分享就到这里。我们下次再见!👋🏻。 阅读详情

作者 | 老郑

来源 | https://juejin.cn/post/6951764927958745124

业务场景

近日在公司领到一个小需求,需要对之前已有的试用用户申请规则进行拓展。我们的场景大概如下所示:

if (是否海外用户) {
 return false;
}

if (刷单用户) {
  return false;
}

if (未付费用户 && 不再服务时段) {
  return false
}

if (转介绍用户 || 付费用户 || 内推用户) {
  return true;
}

按照上述的条件我们可以得出的结论是:

  • 咱们的的主要流程主要是基于 and 或者 or 的关系。

  • 如果有一个不匹配的话,其实咱们后续的流程是不用执行的,就是需要具备一个短路的功能。

  • 对于目前的现状来说,我如果在原有的基础上来改,只要稍微注意一下解决需求不是很大的问题,但是说后面可维护性非常差。

后面进过权衡过后,我还是决定将这个部分进行重构一下。

规则执行器

针对这个需求,我首先梳理了一下咱们规则执行器大概的设计, 然后我设计了一个 V1 版本和大家一起分享一下,如果大家也有这样的 case 可以给我分享留言,下面部分主要是设计和实现的流程和 code.

规则执行器的设计

低代码平台如何一步步摧毁开发团队的效率与创新!

对于规则的抽象并实现规则
// 业务数据
@Data
public class RuleDto {
  private String address;
 private int age;
}

// 规则抽象
public interface BaseRule {

    boolean execute(RuleDto dto);
}

// 规则模板
public abstract class AbstractRule implements BaseRule {

    protected <T> T convert(RuleDto dto) {
        return (T) dto;
    }

    @Override
    public boolean execute(RuleDto dto) {
        return executeRule(convert(dto));
    }
  
    protected <T> boolean executeRule(T t) {
        return true;
    }
}

// 具体规则- 例子1
public class AddressRule extends AbstractRule {

    @Override
    public boolean execute(RuleDto dto) {
        System.out.println("AddressRule invoke!");
        if (dto.getAddress().startsWith(MATCH_ADDRESS_START)) {
            return true;
        }
        return false;
    }
}

// 具体规则- 例子2
public class NationalityRule extends AbstractRule {

    @Override
    protected <T> T convert(RuleDto dto) {
        NationalityRuleDto nationalityRuleDto = new NationalityRuleDto();
        if (dto.getAddress().startsWith(MATCH_ADDRESS_START)) {
            nationalityRuleDto.setNationality(MATCH_NATIONALITY_START);
        }
        return (T) nationalityRuleDto;
    }


    @Override
    protected <T> boolean executeRule(T t) {
        System.out.println("NationalityRule invoke!");
        NationalityRuleDto nationalityRuleDto = (NationalityRuleDto) t;
        if (nationalityRuleDto.getNationality().startsWith(MATCH_NATIONALITY_START)) {
            return true;
        }
        return false;
    }
}

// 常量定义
public class RuleConstant {
    public static final String MATCH_ADDRESS_START= "北京";
    public static final String MATCH_NATIONALITY_START= "中国";
}
执行器构建
public class RuleService {

    private Map<Integer, List<BaseRule>> hashMap = new HashMap<>();
    private static final int AND = 1;
    private static final int OR = 0;

    public static RuleService create() {
        return new RuleService();
    }


    public RuleService and(List<BaseRule> ruleList) {
        hashMap.put(AND, ruleList);
        return this;
    }

    public RuleService or(List<BaseRule> ruleList) {
        hashMap.put(OR, ruleList);
        return this;
    }

    public boolean execute(RuleDto dto) {
        for (Map.Entry<Integer, List<BaseRule>> item : hashMap.entrySet()) {
            List<BaseRule> ruleList = item.getValue();
            switch (item.getKey()) {
                case AND:
                    // 如果是 and 关系,同步执行
                    System.out.println("execute key = " + 1);
                    if (!and(dto, ruleList)) {
                        return false;
                    }
                    break;
                case OR:
                    // 如果是 or 关系,并行执行
                    System.out.println("execute key = " + 0);
                    if (!or(dto, ruleList)) {
                        return false;
                    }
                    break;
                default:
                    break;
            }
        }
        return true;
    }

    private boolean and(RuleDto dto, List<BaseRule> ruleList) {
        for (BaseRule rule : ruleList) {
            boolean execute = rule.execute(dto);
            if (!execute) {
                // and 关系匹配失败一次,返回 false
                return false;
            }
        }
        // and 关系全部匹配成功,返回 true
        return true;
    }

    private boolean or(RuleDto dto, List<BaseRule> ruleList) {
        for (BaseRule rule : ruleList) {
            boolean execute = rule.execute(dto);
            if (execute) {
                // or 关系匹配到一个就返回 true
                return true;
            }
        }
        // or 关系一个都匹配不到就返回 false
        return false;
    }
}
执行器的调用
public class RuleServiceTest {

    @org.junit.Test
    public void execute() {
        //规则执行器
        //优点:比较简单,每个规则可以独立,将规则,数据,执行器拆分出来,调用方比较规整
        //缺点:数据依赖公共传输对象 dto

        //1. 定义规则  init rule
        AgeRule ageRule = new AgeRule();
        NameRule nameRule = new NameRule();
        NationalityRule nationalityRule = new NationalityRule();
        AddressRule addressRule = new AddressRule();
        SubjectRule subjectRule = new SubjectRule();

        //2. 构造需要的数据 create dto
        RuleDto dto = new RuleDto();
        dto.setAge(5);
        dto.setName("张三");
        dto.setAddress("北京");
        dto.setSubject("数学");;

        //3. 通过以链式调用构建和执行 rule execute
        boolean ruleResult = RuleService
                .create()
                .and(Arrays.asList(nationalityRule, nameRule, addressRule))
                .or(Arrays.asList(ageRule, subjectRule))
                .execute(dto);
        System.out.println("this student rule execute result :" + ruleResult);
    }
}

总结

规则执行器的优点和缺点

优点:
  • 比较简单,每个规则可以独立,将规则,数据,执行器拆分出来,调用方比较规整;

  • 我在 Rule 模板类中定义 convert 方法做参数的转换这样可以能够,为特定 rule 需要的场景数据提供拓展。

缺点:
  • 上下 rule 有数据依赖性,如果直接修改公共传输对象 dto 这样设计不是很合理,建议提前构建数据。

分析以太网帧结构_100G以太网接口调试初体验 是的,标题没有多敲一个“0”,明人不说暗话,就是在FPGA上实现100G以太网接口设计。正好参与了实验室某项目中的100G接口的调试,早想写个专栏文章了,由于调试过程中发现了一些硬件问题,导致迟迟没有往前推进,现在问题解决了之后可以简单分享一下100G以太网接口的调试初体验了~(好像DDR4读写测试系列文章还没搞完 )这篇初体验暂时不分多个章节了,基本设计流程与之前发布的“10G以太网接口”系列文... 阅读详情

相关推荐

Label Studio保姆级教程:从零搭建医疗影像标注平台(DICOM格式支持)

本文提供基于Label Studio从零搭建医疗影像标注平台的保姆级教程。针对DICOM格式支持,详细阐述了环境部署、DICOM深度集成与预处理、团队协作权限管理以及质量审核闭环等核心环节,旨在构建一个高效、可落地的医疗AI数据标注解决方案,助力模型落地。

nft7creator的博客 306

使用规则执行器替换java中if语句

使用规则执行器替换java中if语句干掉 if else,让代码容易扩展1.首先2.用户基类3.规则校验基类4.用户信息校验规则基类5.用户校验规则实现类,这里我写了两个,分别校验(UserInfo.addr是否以北京开头)和(UserInfo.age>=18)6.最重要的规则实现类7.测试 干掉 if else,让代码容易扩展 在公众号(链接:https://mp.weixin.qq.com/s/33S0KgZuGjddwY9gyAa1Iw)中看到这样一个规则执行器用来替换掉大量的if语句,本想在本

weixin_40187536的博客 1107

SolidWorks + AI:利用 DeepSeek AI 自动生成 VBA Macro 宏,实现智能化建模!

本教程介绍如何将集成到插件,实现的自动化操作。通过 DeepSeek AI,您可以快速生成高效的,提升!💡。

SolidWorksAPI的专栏 1万+

java中的规则执行器

用来处理大量的if 的判断逻辑,其包含and 与or的穿插使用。

weixin_44576239的博客 373

电路仿真软件PSIM简介

PSIM的基本使用操作...

qq_55203246的博客 7185

S7-1200PLC 与温控仪表Modbus RTU通信

硬件:cpu 1214C 目的:通过Modbus RTU协议,实现对温控仪表的控制 软件:Portal V14SP1

weixin_43922025的博客 3万+

Spark sql规则执行器RuleExecutor(源码解析)

静下心来读源码,给想要了解spark sql底层解析原理的小伙伴们!【本文大纲】1、前言2、Strategy3、Batch(包含一个或多个Rule及一个策略)4、batches: Seq[Batch](Batch队列)5、execute(核心方法)

xiaoluobutou的专栏 478

终端里藏了个AI大神!DeepSeek‑TUI让你的命令行直接起飞

DeepSeek-TUI:终端AI编程神器 DeepSeek-TUI是一款专为开发者设计的终端AI编程工具,基于DeepSeek V4模型,提供100万Token超大上下文支持,适合处理复杂项目。其核心优势包括: 轻量高效:单二进制文件,无需依赖环境,支持SSH远程操作 智能交互:实时流式输出推理过程,支持三档模式(Plan/Agent/YOLO)灵活切换 强大功能:集成文件读写、Git管理、Shell执行等工具,支持一键回滚和持久会话 节省成本:智能压缩与缓存优化,显著降低Token消耗 适用于服务器开发

968
上一篇: Docker 不香吗,为啥还要 K8s ?
下一篇: 鸿蒙OS 2.0流畅度实测,真的比安卓差吗?
Java思维导图
博客等级 码龄10年 306粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值