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