规则执行器的设计实现

Posted dingwen_blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了规则执行器的设计实现相关的知识,希望对你有一定的参考价值。

文章目录

规则执行器的设计实现

[!NOTE]

此规则执行器的设计旨在替代大量的ifelse ifelse嵌套,对代码进行优化。

其他规则以及实体,使用案例中使用的规则类参考完整代码。地址:https://gitee.com/dingwen-gitee/java8-study.git

1.使用场景

if (条件一)
  


if (条件二)
  


if (条件三)
  

...
  
  
if ()
  
else if ()
  
else 
  



if (条件1 && 条件2 || 条件3)
  


...

switch(条件)
    case: 条件1:
    break;
    ...

2.规则dto

package rule;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 规则Dto
 * 业务数据
 * </P>
 *
 * @author dingwen
 * @date 2021.09.09 09:52
 */
public class RuleDto<T> 
    /**
     * 规则Dto值
     */
    private T value;

    public T getValue() 
        return value;
    

    public void setValue(T value) 
        this.value = value;
    


3.规则的抽象接口

  • 多条件返回Boolean类型
  • 多条件返回任意类型
  • 多条件无返回值(按照指定规则执行)
package rule;

/**
 * <p>
 * 规则的抽象接口
 * </P>
 *
 * @author dingwen
 * @date 2021.09.09 09:57
 */
public abstract class AbstractBaseRule<R, T> 

    /**
     * 执行
     *
     * @param ruleDto 规则dto
     * @return @link Boolean
     */
    Boolean executeBoolean(RuleDto<T> ruleDto) 
        return false;
    

    /**
     * 执行
     *
     * @param ruleDto 规则dto
     * @return @link R
     */
    R executeObject(RuleDto<T> ruleDto) 
        return null;
    

    /**
     * 执行
     * 没有返回值
     *
     * @param ruleDto 规则dto
     */
    void executeVoid(RuleDto<T> ruleDto)
    


4.规则执行器

package rule;


import org.omg.CORBA.ORB;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 执行器构建规则服务
 * </P>
 *
 * @author dingwen
 * @date 2021.09.09 10:39
 */
public class RuleService<R, T> 
    /**
     * 规则对象集合
     */
    private final Map<Integer, List<AbstractBaseRule<R, T>>> ruleMap = new HashMap<>();

    /**
     * AND 规则列表
     */
    private final List<AbstractBaseRule<R, T>> ruleAndList = new ArrayList<>();
    /**
     * or 规则列表
     */
    private final List<AbstractBaseRule<R, T>> ruleOrList = new ArrayList<>();

    /**
     * 类型:
     * 1: AND
     * 0: OR
     */
    private int type = 1;

    /**
     * 和
     */
    private static final int AND = 1;
    /**
     * 或
     */
    private static final int OR = 0;

    private RuleService() 
    

    public static <R, T> RuleService<R, T> getInstance() 
        return new RuleService<>();
    


    /**
     * 和
     *
     * @return @link RuleService<>
     */
    public final RuleService<R, T> and() 
        type = AND;
        return this;
    


    /**
     * 或
     *
     * @return @link RuleService<>
     */
    public final RuleService<R, T> or() 
        type = OR;
        return this;
    

    /**
     * 构建器
     *
     * @param rule 规则
     * @return @link RuleService<>
     */
    public RuleService<R, T> builder(AbstractBaseRule<R, T> rule) 
        if (type == AND) 
            ruleAndList.add(rule);
         else 
            ruleOrList.add(rule);
        
        return this;
    

    /**
     * 构建
     *
     * @return @link RuleService<>
     */
    public RuleService<R, T> build() 
        if (type == AND) 
            ruleMap.put(AND, ruleAndList);
         else 
            ruleMap.put(OR, ruleOrList);
        
        return this;
    


    /**
     * 和
     *
     * @param ruleDto  规则dto
     * @param ruleList 规则列表
     * @return @link Boolean
     */
    private Boolean and(RuleDto<T> ruleDto, List<AbstractBaseRule<R, T>> ruleList) 
        return ruleList.stream().parallel().allMatch(rtAbstractBaseRule -> rtAbstractBaseRule.executeBoolean(ruleDto));
    


    /**
     * 或
     *
     * @param ruleDto  规则dto
     * @param ruleList 规则列表
     * @return @link Boolean
     */
    private Boolean or(RuleDto<T> ruleDto, List<AbstractBaseRule<R, T>> ruleList) 
        return ruleList.stream().parallel().anyMatch(rtAbstractBaseRule -> rtAbstractBaseRule.executeBoolean(ruleDto));
    


    /**
     * 执行
     *
     * @param ruleDto 规则dto
     * @return @link Boolean
     */
    public Boolean execute(RuleDto<T> ruleDto) 
        boolean result = false;
        if (ruleMap.containsKey(AND) && !ruleMap.containsKey(OR)) 
            result = and(ruleDto, ruleMap.get(AND));
         else if (!ruleMap.containsKey(AND) && ruleMap.containsKey(OR)) 
            result = or(ruleDto, ruleMap.get(OR));
         else if (ruleMap.containsKey(AND) && ruleMap.containsKey(OR)) 
            if (type == AND) 
                result = and(ruleDto, ruleMap.get(AND)) && or(ruleDto, ruleMap.get(AND));
             else 
                result = and(ruleDto, ruleMap.get(OR)) || or(ruleDto, ruleMap.get(OR));
            
         else 
            return false;
        
        ruleMap.clear();
        return result;
    


    /**
     * 执行
     *
     * @param ruleDto 规则dto
     * @param rule    规则
     * @return @link R
     */
    public R execute(RuleDto<T> ruleDto, AbstractBaseRule<R, T> rule) 
        return rule.executeObject(ruleDto);
    

    /**
     * 执行
     * 没有返回值
     *
     * @param ruleDto 规则dto
     * @param rule    规则
     */
    public void executeVoid(RuleDto<T> ruleDto, AbstractBaseRule<R, T> rule) 
        rule.executeVoid(ruleDto);
    

5.使用

package rule;

import entity.Student;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 *  测试
 * </P>
 *
 * @author dingwen
 * @date 2021.09.09 12:01
 */
public class Test 
    public static void main(String[] args) 

        // 多值多判断情况
        RuleDto<Map<String, String>> usernameRuleDto = new RuleDto<>();

        HashMap<String, String> valueMap = new HashMap<>(2);
        valueMap.put(UserNameRule.class.getSimpleName(), "dingwen");
        valueMap.put(PasswordRule.class.getSimpleName(), "123456");
        usernameRuleDto.setValue(valueMap);

        RuleService<Boolean, Map<String, String>> ruleService = RuleService.getInstance();
//        Boolean r1 = ruleService.and()
//                .builder(new UserNameRule("dingwen"))
//                .builder(new PasswordRule())
//                .build()
//                .execute(usernameRuleDto);
//
//        System.out.println("r1 = " + r1);
//
//        Boolean r2 = ruleService.or()
//                .builder(new UserNameRule("dingwen"))
//                .builder(new PasswordRule())
//                .build()
//                .and()
//                .builder(new UserNameRule("dingwen"))
//                .builder(new PasswordRule())
//                .build()
//                .execute(usernameRuleDto);
//        System.out.println("r2 = " + r2);

//        Boolean r3 = ruleService.or()
//                .builder(new UserNameRule("din1gwen"))
//                .builder(new PasswordRule())
//                .build()
//                .or()
//                .builder(new UserNameRule("dingwen"))
//                .builder(new PasswordRule())
//                .build()
//                .execute(usernameRuleDto);
//        System.out.println("r3 = " + r3);

//        Boolean r4 = ruleService.and()
//                .builder(new UserNameRule("dingwen"))
//                .builder(new PasswordRule())
//                .build()
//                .and()
//                .builder(new UserNameRule("dingwen"))
//                .builder(new PasswordRule())
//                .build()
//                .execute(usernameRuleDto);
//        System.out.println("r4 = " + r4);


                Boolean r6 = ruleService.and()
                .builder(new UserNameRule("dingwen"))
                .builder(new PasswordRule())
                .build()
                .or()
                .builder(new UserNameRule("dingwen"))
                .builder(new PasswordRule())
                .build()
                .execute(usernameRuleDto);
        System.out.println("r6 = " + r6);


//        // 指定规则指定返回类型
//        RuleDto<Student> studentRuleDto = new RuleDto<>();
//        Student student = new Student();
//        student.setName("dingwen");
//        studentRuleDto.setValue(student);
//        Double sore = RuleService.<Double, Student>getInstance().execute(studentRuleDto, new StudentRule());
//        System.out.println("sore = " + sore);
//
//        // 指定规则没有返回值
//
//        RuleDto<String> stringRuleDto = new RuleDto<>();
//        stringRuleDto.setValue("y");
//
//        RuleService.<Object,String>getInstance().executeVoid(stringRuleDto,new PrintRule());
//
//
//        // 一个条件对应不同返回值
//        RuleDto<String> ruleDto = new RuleDto<>();
//        ruleDto.setValue("张三");
//        RuleService<Student, String> ruleService1 = RuleService.getInstance();
//        Student student1 = ruleService1.execute(ruleDto, new Student2Rule());
//        System.out.println("student1 = " + student1);


    


以上是关于规则执行器的设计实现的主要内容,如果未能解决你的问题,请参考以下文章

代理设计模式

借助尾号限行 API 实现限行规则应用的设计思路分析

c# 中的规则引擎设计和示例

数据库设计三大范式

SQL 获取名字拼音

SQL题:请用一条SQL查询(ORACLE)语言实现行列转换