马府强
2 years ago
26 changed files with 314 additions and 0 deletions
@ -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/ |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="CompilerConfiguration"> |
||||
|
<annotationProcessing> |
||||
|
<profile default="true" name="Default" enabled="true" /> |
||||
|
<profile name="Maven default annotation processors profile" enabled="true"> |
||||
|
<sourceOutputDir name="target/generated-sources/annotations" /> |
||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> |
||||
|
<outputRelativeToContentRoot value="true" /> |
||||
|
<module name="roledemo" /> |
||||
|
</profile> |
||||
|
</annotationProcessing> |
||||
|
</component> |
||||
|
</project> |
@ -0,0 +1,20 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="RemoteRepositoriesConfiguration"> |
||||
|
<remote-repository> |
||||
|
<option name="id" value="central" /> |
||||
|
<option name="name" value="Central Repository" /> |
||||
|
<option name="url" value="https://repo.maven.apache.org/maven2" /> |
||||
|
</remote-repository> |
||||
|
<remote-repository> |
||||
|
<option name="id" value="central" /> |
||||
|
<option name="name" value="Maven Central repository" /> |
||||
|
<option name="url" value="https://repo1.maven.org/maven2" /> |
||||
|
</remote-repository> |
||||
|
<remote-repository> |
||||
|
<option name="id" value="jboss.community" /> |
||||
|
<option name="name" value="JBoss Community repository" /> |
||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> |
||||
|
</remote-repository> |
||||
|
</component> |
||||
|
</project> |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project version="4"> |
||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" /> |
||||
|
<component name="MavenProjectsManager"> |
||||
|
<option name="originalFiles"> |
||||
|
<list> |
||||
|
<option value="$PROJECT_DIR$/pom.xml" /> |
||||
|
</list> |
||||
|
</option> |
||||
|
</component> |
||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK"> |
||||
|
<output url="file://$PROJECT_DIR$/out" /> |
||||
|
</component> |
||||
|
</project> |
@ -0,0 +1,21 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<groupId>com.woniu</groupId> |
||||
|
<artifactId>roledemo</artifactId> |
||||
|
<version>1.0-SNAPSHOT</version> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.projectlombok</groupId> |
||||
|
<artifactId>lombok</artifactId> |
||||
|
<version>1.18.24</version> |
||||
|
</dependency> |
||||
|
|
||||
|
</dependencies> |
||||
|
|
||||
|
|
||||
|
</project> |
@ -0,0 +1,2 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<module type="JAVA_MODULE" version="4" /> |
@ -0,0 +1,19 @@ |
|||||
|
package com.woniu.roledemo; |
||||
|
|
||||
|
|
||||
|
// 规则模板
|
||||
|
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; |
||||
|
} |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
package com.woniu.roledemo; |
||||
|
|
||||
|
// 规则抽象
|
||||
|
public interface BaseRule { |
||||
|
boolean execute(RuleDto dto); |
||||
|
} |
@ -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; |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package com.woniu.roledemo; |
||||
|
|
||||
|
|
||||
|
// 具体规则- 例子2
|
||||
|
public class NationalityRule extends AbstractRule { |
||||
|
|
||||
|
@Override |
||||
|
protected <T> 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 <T> 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; |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
package com.woniu.roledemo; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
@Data |
||||
|
public class NationalityRuleDto { |
||||
|
|
||||
|
private String nationality; |
||||
|
} |
@ -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 = "中国"; |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
package com.woniu.roledemo; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
// 业务数据
|
||||
|
@Data |
||||
|
public class RuleDto { |
||||
|
private String address; |
||||
|
private String name; |
||||
|
private int age; |
||||
|
} |
@ -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<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; |
||||
|
} |
||||
|
} |
@ -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); |
||||
|
} |
||||
|
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue