diff --git a/roledemo/.idea/.gitignore b/roledemo/.idea/.gitignore new file mode 100644 index 0000000..2af0652 --- /dev/null +++ b/roledemo/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/../../../../:\java project\roledemo\.idea/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/roledemo/.idea/compiler.xml b/roledemo/.idea/compiler.xml new file mode 100644 index 0000000..0cda0c8 --- /dev/null +++ b/roledemo/.idea/compiler.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/roledemo/.idea/jarRepositories.xml b/roledemo/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/roledemo/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/roledemo/.idea/misc.xml b/roledemo/.idea/misc.xml new file mode 100644 index 0000000..4b661a5 --- /dev/null +++ b/roledemo/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/roledemo/pom.xml b/roledemo/pom.xml new file mode 100644 index 0000000..cd85f01 --- /dev/null +++ b/roledemo/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + + com.woniu + roledemo + 1.0-SNAPSHOT + + + + org.projectlombok + lombok + 1.18.24 + + + + + + \ No newline at end of file diff --git a/roledemo/roledemo.iml b/roledemo/roledemo.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/roledemo/roledemo.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/roledemo/src/main/java/com/woniu/roledemo/AbstractRule.java b/roledemo/src/main/java/com/woniu/roledemo/AbstractRule.java new file mode 100644 index 0000000..fd25b59 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/AbstractRule.java @@ -0,0 +1,19 @@ +package com.woniu.roledemo; + + +// 规则模板 +public abstract class AbstractRule implements BaseRule { + + protected T convert(RuleDto dto) { + return (T) dto; + } + + @Override + public boolean execute(RuleDto dto) { + return executeRule(convert(dto)); + } + + protected boolean executeRule(T t) { + return true; + } +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/AddressRule.java b/roledemo/src/main/java/com/woniu/roledemo/AddressRule.java new file mode 100644 index 0000000..ba0566f --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/AddressRule.java @@ -0,0 +1,15 @@ +package com.woniu.roledemo; + + +// 具体规则- 例子1 +public class AddressRule extends AbstractRule { + + @Override + public boolean execute(RuleDto dto) { + System.out.println("AddressRule invoke!"); + if (dto.getAddress().startsWith(RuleConstant.MATCH_ADDRESS_START)) { + return true; + } + return false; + } +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/BaseRule.java b/roledemo/src/main/java/com/woniu/roledemo/BaseRule.java new file mode 100644 index 0000000..76064e5 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/BaseRule.java @@ -0,0 +1,6 @@ +package com.woniu.roledemo; + +// 规则抽象 +public interface BaseRule { + boolean execute(RuleDto dto); +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/NameRule.java b/roledemo/src/main/java/com/woniu/roledemo/NameRule.java new file mode 100644 index 0000000..c594c39 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/NameRule.java @@ -0,0 +1,14 @@ +package com.woniu.roledemo; + + +public class NameRule extends AbstractRule { + + @Override + public boolean execute(RuleDto dto) { + System.out.println("NameRule invoke!"); + if (dto.getName().startsWith("woniu")) { + return true; + } + return false; + } +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/NationalityRule.java b/roledemo/src/main/java/com/woniu/roledemo/NationalityRule.java new file mode 100644 index 0000000..cc34fd4 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/NationalityRule.java @@ -0,0 +1,26 @@ +package com.woniu.roledemo; + + +// 具体规则- 例子2 +public class NationalityRule extends AbstractRule { + + @Override + protected T convert(RuleDto dto) { + NationalityRuleDto nationalityRuleDto = new NationalityRuleDto(); + if (dto.getAddress().startsWith(RuleConstant.MATCH_ADDRESS_START)) { + nationalityRuleDto.setNationality(RuleConstant.MATCH_NATIONALITY_START); + } + return (T) nationalityRuleDto; + } + + + @Override + protected boolean executeRule(T t) { + System.out.println("NationalityRule invoke!"); + NationalityRuleDto nationalityRuleDto = (NationalityRuleDto) t; + if (nationalityRuleDto.getNationality().startsWith(RuleConstant.MATCH_NATIONALITY_START)) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/roledemo/src/main/java/com/woniu/roledemo/NationalityRuleDto.java b/roledemo/src/main/java/com/woniu/roledemo/NationalityRuleDto.java new file mode 100644 index 0000000..5310e76 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/NationalityRuleDto.java @@ -0,0 +1,9 @@ +package com.woniu.roledemo; + +import lombok.Data; + +@Data +public class NationalityRuleDto { + + private String nationality; +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/RuleConstant.java b/roledemo/src/main/java/com/woniu/roledemo/RuleConstant.java new file mode 100644 index 0000000..d4eb597 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/RuleConstant.java @@ -0,0 +1,6 @@ +package com.woniu.roledemo; + +public class RuleConstant { + public static final String MATCH_ADDRESS_START = "北京"; + public static final String MATCH_NATIONALITY_START = "中国"; +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/RuleDto.java b/roledemo/src/main/java/com/woniu/roledemo/RuleDto.java new file mode 100644 index 0000000..54b740b --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/RuleDto.java @@ -0,0 +1,11 @@ +package com.woniu.roledemo; + +import lombok.Data; + +// 业务数据 +@Data +public class RuleDto { + private String address; + private String name; + private int age; +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/RuleService.java b/roledemo/src/main/java/com/woniu/roledemo/RuleService.java new file mode 100644 index 0000000..82a2ed9 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/RuleService.java @@ -0,0 +1,77 @@ +package com.woniu.roledemo; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RuleService { + + private Map> 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 ruleList) { + hashMap.put(AND, ruleList); + return this; + } + + public RuleService or(List ruleList) { + hashMap.put(OR, ruleList); + return this; + } + + public boolean execute(RuleDto dto) { + for (Map.Entry> item : hashMap.entrySet()) { + List 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 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 ruleList) { + for (BaseRule rule : ruleList) { + boolean execute = rule.execute(dto); + if (execute) { + // or 关系匹配到一个就返回 true + return true; + } + } + // or 关系一个都匹配不到就返回 false + return false; + } +} diff --git a/roledemo/src/main/java/com/woniu/roledemo/RuleServiceTest.java b/roledemo/src/main/java/com/woniu/roledemo/RuleServiceTest.java new file mode 100644 index 0000000..1ede370 --- /dev/null +++ b/roledemo/src/main/java/com/woniu/roledemo/RuleServiceTest.java @@ -0,0 +1,52 @@ +package com.woniu.roledemo; + + +import java.util.Arrays; + +/** + * + * 还在写大量 if 来判断?试试用一个规则执行器神器吧! + * + * if (是否海外用户) { + * return false; + * } + * + * if (刷单用户) { + * return false; + * } + * + * if (未付费用户 && 不再服务时段) { + * return false + * } + * + * if (转介绍用户 || 付费用户 || 内推用户) { + * return true; + * } + */ +public class RuleServiceTest { + + public static void main(String[] args) { + //规则执行器 + //优点:比较简单,每个规则可以独立,将规则,数据,执行器拆分出来,调用方比较规整 + //缺点:数据依赖公共传输对象 dto + + //1. 定义规则 init rule + NationalityRule nationalityRule = new NationalityRule(); + AddressRule addressRule = new AddressRule(); + NameRule nameRule = new NameRule(); + + //2. 构造需要的数据 create dto + RuleDto dto = new RuleDto(); + dto.setAge(5); + dto.setName("haha"); + dto.setAddress("南京"); + + //3. 通过以链式调用构建和执行 rule execute + boolean ruleResult = RuleService + .create() + .and(Arrays.asList(nationalityRule, addressRule)) + .or(Arrays.asList(nameRule)) + .execute(dto); + System.out.println("this rule execute result :" + ruleResult); + } +} diff --git a/roledemo/target/classes/com/woniu/roledemo/AbstractRule.class b/roledemo/target/classes/com/woniu/roledemo/AbstractRule.class new file mode 100644 index 0000000..4a26e4a Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/AbstractRule.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/AddressRule.class b/roledemo/target/classes/com/woniu/roledemo/AddressRule.class new file mode 100644 index 0000000..f166598 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/AddressRule.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/BaseRule.class b/roledemo/target/classes/com/woniu/roledemo/BaseRule.class new file mode 100644 index 0000000..0c94044 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/BaseRule.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/NameRule.class b/roledemo/target/classes/com/woniu/roledemo/NameRule.class new file mode 100644 index 0000000..11fb383 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/NameRule.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/NationalityRule.class b/roledemo/target/classes/com/woniu/roledemo/NationalityRule.class new file mode 100644 index 0000000..c6d0676 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/NationalityRule.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/NationalityRuleDto.class b/roledemo/target/classes/com/woniu/roledemo/NationalityRuleDto.class new file mode 100644 index 0000000..15fda5d Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/NationalityRuleDto.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/RuleConstant.class b/roledemo/target/classes/com/woniu/roledemo/RuleConstant.class new file mode 100644 index 0000000..1ef495f Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/RuleConstant.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/RuleDto.class b/roledemo/target/classes/com/woniu/roledemo/RuleDto.class new file mode 100644 index 0000000..e135c97 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/RuleDto.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/RuleService.class b/roledemo/target/classes/com/woniu/roledemo/RuleService.class new file mode 100644 index 0000000..669aec1 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/RuleService.class differ diff --git a/roledemo/target/classes/com/woniu/roledemo/RuleServiceTest.class b/roledemo/target/classes/com/woniu/roledemo/RuleServiceTest.class new file mode 100644 index 0000000..60605d8 Binary files /dev/null and b/roledemo/target/classes/com/woniu/roledemo/RuleServiceTest.class differ