规则执行器的设计实现
Posted dingwen_blog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了规则执行器的设计实现相关的知识,希望对你有一定的参考价值。
规则执行器的设计实现
[!NOTE]
此规则执行器的设计旨在替代大量的
if
、else if
、else
嵌套,对代码进行优化。其他规则以及实体,使用案例中使用的规则类参考完整代码。地址: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);
}
}
以上是关于规则执行器的设计实现的主要内容,如果未能解决你的问题,请参考以下文章