温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java多条件判断场景中规则执行器的示例分析

发布时间:2021-06-26 09:10:32 来源:亿速云 阅读:518 作者:小新 栏目:开发技术

这篇文章主要介绍Java多条件判断场景中规则执行器的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

业务场景

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

if (是否海外用户) {  return false; } if (刷单用户) {   return false; } if (未付费用户 && 不再服务时段) {   return false } if (转介绍用户 || 付费用户 || 内推用户) {   return true; }

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

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

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

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

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

规则执行器

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

规则执行器的设计

Java多条件判断场景中规则执行器的示例分析

对于规则的抽象并实现规则

// 业务数据 @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 这样设计不是很合理,建议提前构建数据。

以上是“Java多条件判断场景中规则执行器的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI