1.使用场景:
这个设计模式一般用来解释语句中的句子,实际开发中EL表达式或者正则表达式的解释器就是采用这种设计模式等。
2.UML表示
Expression:抽象表达式,用来表明所有具体表达式需要实现的抽象接口。
Terminal Expression:终结符表达式,实现了抽象表达式所要求的接口。
Nonterminal Expression:非终结表达式
Context:环境,它的任务一般用来存放文法中各个终结符对应的具体值。
具体的UML示意图如下:
3.代码实现
这里参考了网络上的例子:https://www.cnblogs.com/chenpi/p/5222496.html
具体就是自定义一个解释器用来解析一种类似后序表达式()的值。
下面是具体的代码:
首先我们定义一个接口:
public interface Expression {
/**
*
* @author lsj
* @date 2018/2/16 11:21
* @param [variables]
* @return int
*/
int interpret(Map<String,Expression> variables);
}
定义符号识别类:
public class Plus implements Expression {
Expression left;
Expression right;
public Plus(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Expression> variables) {
return left.interpret(variables)+right.interpret(variables);
}
}
public class Minus implements Expression{
Expression left;
Expression right;
public Minus(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Expression> variables) {
return left.interpret(variables)-right.interpret(variables);
}
}
public class Number implements Expression {
private int number;
public Number(int number) {
this.number = number;
}
@Override
public int interpret(Map<String, Expression> variables) {
return number;
}
}
定义解析类:
public class Variable implements Expression {
private String name;
public Variable(String name) {
this.name = name;
}
@Override
public int interpret(Map<String, Expression> variables) {
if (null==variables.get(name))
return 0;
return variables.get(name).interpret(variables);
}
}
public class Evaluator implements Expression {
private Expression syntaxTree;
public Evaluator(String expression){
Stack<Expression> expressions=new Stack<>();
for (String token:expression.split(" ")){
if (token.equals("+")){
Expression subExpression=new Plus(expressions.pop(),expressions.pop());
expressions.push(subExpression);
}else if(token.equals("-")){
Expression right=expressions.pop();
Expression left=expressions.pop();
Expression subExpression=new Minus(left,right);
expressions.push(subExpression);
}
else{
expressions.push(new Variable(token));
}
}
syntaxTree=expressions.pop();
}
@Override
public int interpret(Map<String, Expression> variables) {
return syntaxTree.interpret(variables);
}
}
最后,编写测试类:
public class Client {
public static void main(String[] args) {
String expression="w x z - +";
Evaluator evaluator=new Evaluator(expression);
Map<String,Expression> variables=new HashMap<>();
variables.put("w",new Number(5));
variables.put("w",new Number(5));
variables.put("w",new Number(5));
int result=evaluator.interpret(variables);
System.out.println(result);
}
}
4.总结
解释器模式主要用于需要自定义语法分析工具的场景,如果需要增加操作,只需要添加具体的类即可。在实际开发中使用率较低。
项目链接:
https://github.com/memoryexplosion/design_pattern_review/tree/master/src/java/interpreter