blic static SingleCondition getInstance(String configJson) {
return JSON.parseObject(configJson, SingleCondition.class);
}
/**
* 单条件测试
* 这里仅做一个demo,实际需考虑健壮性和更多因素
*/
@Override
public boolean satisfiedBy(Map<String, Object> valueMap) {
return this.cond.test(valueMap);
}
}
STEP4: 按钮逻辑是组合条件,必须所有条件 conditions 都满足才算测试通过,返回 Result ; 否则交由下一个条件逻辑配置处理。
package zzz.study.patterns.composite.button;
import com.alibaba.fastjson.JSON;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.Data;
@Data
public class MultiCondition implements ICondition {
private List<BaseCondition> conditions;
private Boolean result;
public MultiCondition() {
this.conditions = new ArrayList<>();
this.result = false;
}
public MultiCondition(List<BaseCondition> conditions, Boolean result) {
this.conditions = conditions;
this.result = result;
}
public static MultiCondition getInstance(String configJson) {
return JSON.parseObject(configJson, MultiCondition.class);
}
@Override
public boolean satisfiedBy(Map<String, Object> valueMap) {
for (BaseCondition bc: conditions) {
if (!bc.test(valueMap)) {
return false;
}
}
return true;
}
}
STEP5: 按钮逻辑配置的抽象:
package zzz.study.patterns.composite.button;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.Data;
@Data
public class ButtonCondition {
private List<ICondition> buttonRules;
private Boolean defaultResult;
public ButtonCondition() {
this.buttonRules = new ArrayList<>();
this.defaultResult = false;
}
public ButtonCondition(List<ICondition> matches, Boolean defaultResult) {
this.buttonRules = matches;
this.defaultResult = defaultResult;
}
public static ButtonCondition getInstance(String configJson) {
Map<String, Object> configMap = JSON.parseObject(configJson);
Boolean result = ((JSONObject) configMap).getBoolean("defaultResult");
JSONArray conditions = ((JSONObject) configMap).getJSONArray("buttonRules");
List<ICondition> allConditions = new ArrayList<>();
for (int i=0; i < conditions.size(); i++) {
Map condition = (Map) conditions.get(i);
if (condition.containsKey("cond")) {
allConditions.add(JSONObject.parseObject(condition.toString(), SingleCondition.class));
}
else if (condition.containsKey("conditions")){
allConditions.add(JSONObject.parseObject(condition.toString(), MultiCondition.class));
}
}
return new ButtonCondition(allConditions, result);
}
public boolean satisfiedBy(Map<String, Object> valueMap) {
// 这里是一个责任链模式,为简单起见,采用了列表遍历
for (ICondition cond: buttonRules) {
if (cond.satisfiedBy(valueMap)) {
return cond.getResult();
}
}
return defaultResult;
}
}
STEP6: 按钮逻辑配置及测试
@Test
def "testConditions"() {
expect:
def singleCondJson = '{"cond":{"field": "activity_type", "op":"eq", "value": 13}, "result": true}