# 23种设计模式-解释器模式
# 1.解释器模式
给定一个语言,定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
# 优缺点
# 优点:
解释器是一个简单的语法分析工具,它最显著的优点就是扩展性,修改语法规则只需要修改相应的非终结符就可以了,若扩展语法,只需要增加非终结符类就可以了。 增加了新的解释表达式的方式。 易于实现文法。
# 缺点:
解释器模式会引起类的膨胀,每个语法都需要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来非常多的麻烦。 效率低下,采用递归调用方法,每个非终结符表达式只关心与自己相关的表达式,每个表达式需要知道最终的结果,必须通过递归方式,无论是面向对象的语言还是面向过程的语言,递归都是一个不推荐的方式。由于使用了大量的循环和递归,效率是一个不容忽视的问题。特别是用于解释一个解析复杂、冗长的语法时,效率是难以忍受的。
# 使用场景
1有一个简单的语法规则,比如一个sql语句,如果我们需要根据sql语句进行rm转换,就可以使用解释器模式来对语句进行解释。
2一些重复发生的问题,比如加减乘除四则运算,但是公式每次都不同,有时是a+b-cd,有时是ab+c-d,等等,公式千变万化,但是都是由加减乘除四个非终结符来连接的,这时我们就可以使用解释器模式。
# 实现方式
# 抽象表达式:Node.java。
public interface Node{
public int interpret();
}
# 非终结表达式:ValueNode.java。主要用解释该表达式的值。
public class ValueNode implements Node{
private int value;
public ValueNode(int value){
this.value=value;
}
public int interpret(){
return this.value;
}
}
# 终结表达式抽象类,由于该终结表达式需要解释多个运算符号,同时用来构建抽象语法树:
public abstract class SymbolNode implements Node{
protected Node left;
protected Node right;
public SymbolNode(Node left,Node right){
this.left=left;
this.right=right;
}
}
# MulNode.java:
public class MulNode extends SymbolNode{
public MulNode(Node left,Node right){
super(left,right);
}
public int interpret(){
return left.interpret() * right.interpret();
}
}
# ModNode.java:
public class ModNode extends SymbolNode{
public ModNode(Node left,Node right){
super(left,right);
}
public int interpret(){
return super.left.interpret() % super.right.interpret();
}
}
# DivNode.java:
public class DivNode extends SymbolNode{
public DivNode(Node left,Node right){
super(left,right);
}
public int interpret(){
return super.left.interpret() / super.right.interpret();
}
}
# Calculator.java:
public class Calculator{
private String statement;
private Node node;
public void build(String statement){
Node left=null,right=null;
Stack stack=new Stack();
String[] statementArr=statement.split(" ");
for(int i=0;i<statementArr.length;i++){
if(statementArr[i].equalsIgnoreCase("*")){
left=(Node)stack.pop();
int val=Integer.parseInt(statementArr[++i]);
right=new ValueNode(val);
stack.push(new MulNode(left,right));
}
else if(statementArr[i].equalsIgnoreCase("/")){
left=(Node)stack.pop();
int val=Integer.parseInt(statementArr[++i]);
right=new ValueNode(val);
stack.push(new DivNode(left,right));
}
else if(statementArr[i].equalsIgnoreCase("%")){
left=(Node)stack.pop();
int val=Integer.parseInt(statementArr[++i]);
right=new ValueNode(val);
stack.push(new ModNode(left,right));
}
else{
stack.push(new ValueNode(Integer.parseInt(statementArr[i])));
}
}
this.node=(Node)stack.pop();
}
public int compute(){
return node.interpret();
}
}
# 测试类
public class Client{
public static void main(String args[]){
String statement = "3 * 2 * 4 / 6 % 5";
Calculator calculator = new Calculator();
calculator.build(statement);
int result = calculator.compute();
System.out.println(statement + " = " + result);
}
}
参考博客:https://blog.csdn.net/a745233700/article/details/83750731