解释器设计模式在自定义告警规则的应用
概述
Interpreter 模式也叫解释器模式,是行为模式之一,它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。简单地说,Interpreter 模式是一种简单的语法解释器构架。 换一种解释就是定义一个语法, 定义一个解释器,该解释器处理该语法句子将某些复杂问题,表达为某种语法规则,然后构建解释器来解释处理这类句子。
角色
Expression(抽象表达式) 声明一个抽象的解释操作。
TerminalExpression(终结符表达式) 实现与文法中的终结符相关联的解释操作
NonterminalExpression(非终结符表达式) 为文法中的非终结符实现解释(Interpret)操作。
Context(上下文) 包含解释器之外的一些全局信息。
Client(客户)构建(或被给定)表示该文法定义的语言中一个特定的句子的抽象语法树
应用场景
- 风控系统中的配置规则报警
- 物联网健康数据监控
案例
在处理大健康医疗系统的时候,我们通常会对每一个用户进行单独的健康指标设置,对应的设备上报的数据要是符合不符合我们的指标,那么我们就会进行对应的事件处理,这个场景就很符合采用解释器设计模式,以下代码是我经过一些简化,保留解释器设计模式的核心代码
定义 Expression
java
public interface Expression {
boolean Interpret(Map<String,Long> param);
}
定义表达式
java
public class GreaterExpression implements Expression {
private final String key;
private final Long value;
public GreaterExpression(String expression) {
String[] elements = expression.trim().split("\\s+");
if (elements.length != 3 || !elements[1].trim().equals(">")) {
throw new UnsupportedOperationException("表达式不正确 " + expression);
}
this.key = elements[0].trim();
this.value = Long.parseLong(elements[2].trim());
}
@Override
public boolean Interpret(Map<String,Long> param) {
if (!param.containsKey(key)) {
return false;
}
Long targetValue = param.get(key);
return targetValue > value;
}
}
public class LessExpression implements Expression{
private final String key;
private final Long value;
public LessExpression(String expression) {
String[] elements = expression.trim().split("\\s+");
if (elements.length != 3 || !elements[1].trim().equals("<")) {
throw new UnsupportedOperationException("表达式不正确 " + expression);
}
this.key = elements[0].trim();
this.value = Long.parseLong(elements[2].trim());
}
@Override
public boolean Interpret(Map<String,Long> params) {
if (!params.containsKey(key)) {
return false;
}
return params.get(key) < this.value;
}
}
public class EqualExpression implements Expression{
private final String key;
private final Long value;
public EqualExpression(String expression) {
String[] elements = expression.trim().split("\\s+");
if (elements.length != 3 || !elements[1].trim().equals("==")) {
throw new UnsupportedOperationException("表达式不正确 " + expression);
}
this.key = elements[0].trim();
this.value = Long.parseLong(elements[2].trim());
}
@Override
public boolean Interpret(Map<String,Long> params) {
if (!params.containsKey(key)){
return false;
}
return params.get(key).equals(this.value);
}
}
public class AndExpression implements Expression{
private List<Expression> expressions = new ArrayList<>();
public AndExpression(String expression) {
String[] splitExpressions = expression.split("&&");
for (String expr : splitExpressions) {
if (expr.contains(">")) {
expressions.add(new GreaterExpression(expr));
} else if (expr.contains("<")) {
expressions.add(new LessExpression(expr));
} else if (expr.contains("==")) {
expressions.add(new EqualExpression(expr));
} else {
throw new UnsupportedOperationException("不支持的类型: " + expr);
}
}
}
public AndExpression(List<Expression> expressions) {
this.expressions.addAll(expressions);
}
@Override
public boolean Interpret(Map<String,Long> params) {
for (Expression expression : expressions) {
if (!expression.Interpret(params)) {
return false;
}
}
return true;
}
}
public class OrExpression implements Expression{
private List<Expression> expressions = new ArrayList<>();
public OrExpression(String expression) {
String[] splitExpressions = expression.split("\\|\\|");
for (String expr : splitExpressions) {
if (expr.contains(">")) {
expressions.add(new GreaterExpression(expr));
} else if (expr.contains("<")) {
expressions.add(new LessExpression(expr));
} else if (expr.contains("==")) {
expressions.add(new EqualExpression(expr));
} else {
throw new UnsupportedOperationException("不支持的类型: " + expr);
}
}
}
public OrExpression(List<Expression> expressions) {
this.expressions.addAll(expressions);
}
@Override
public boolean Interpret(Map<String,Long> params) {
for (Expression expression : expressions) {
if (expression.Interpret(params)) {
return true;
}
}
return false;
}
}
定义 Conetext 对象
java
public class AlarmRuleInterpreter {
private Expression expression;
public AlarmRuleInterpreter(Expression expression) {
this.expression = expression;
}
public boolean Interpret(Map<String,Long> params) {
return this.expression.Interpret(params);
}
public void setExpression(Expression expression) {
this.expression = expression;
}
}
测试
java
public class Client {
public static void main(String[] args) {
GreaterExpression greaterExpression = new GreaterExpression("heartRate > 60");
AlarmRuleInterpreter alarmRuleInterpreter = new AlarmRuleInterpreter(greaterExpression);
System.out.println(alarmRuleInterpreter.Interpret(Map.of("heartRate", 70L)));
System.out.println(alarmRuleInterpreter.Interpret(Map.of("heartRate", 60L)));
LessExpression lessExpression = new LessExpression("heartRate < 70");
alarmRuleInterpreter.setExpression(lessExpression);
System.out.println(alarmRuleInterpreter.Interpret(Map.of("heartRate",60L)));
System.out.println(alarmRuleInterpreter.Interpret(Map.of("heartRate",71L)));
EqualExpression equalExpression = new EqualExpression("heartRate == 70");
alarmRuleInterpreter.setExpression(equalExpression);
System.out.println(alarmRuleInterpreter.Interpret(Map.of("heartRate",60L)));
System.out.println(alarmRuleInterpreter.Interpret(Map.of("heartRate",70L)));
AndExpression andExpression = new AndExpression("SBP > 90 && SBP < 140 && DBP > 60 && DBP < 90");
alarmRuleInterpreter.setExpression(andExpression);
System.out.println("AND " + alarmRuleInterpreter.Interpret(Map.of("SBP", 120L, "DBP", 80L)));
System.out.println("AND " + alarmRuleInterpreter.Interpret(Map.of("SBP", 120L, "DBP", 100L)));
OrExpression orExpression = new OrExpression("SBP > 90 || SBP < 140 || DBP > 60 || DBP < 90");
alarmRuleInterpreter.setExpression(orExpression);
System.out.println("or " + alarmRuleInterpreter.Interpret(Map.of("SBP", 120L, "DBP", 80L)));
}
}