请选择 ‘文档’ 后再开始编辑!解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子
场景
- 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
- 简单的语法需要解释时,如解释一个sql语句
实现
主要的构成角色如下:
- AbstractExpression:抽象解释器,声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享
- TerminalExpression:终结解释器,实现与文法中的终结符相关联的解释操作。一个句子中的每一个终结符需要该类的一个实例
- NonterminalExpression:非终结解释器,对文法中的规则的解释操作
- Context:环境角色,包含解释器之外的一些全局信息,一般可由HashMap实现
实现波兰表达式的后缀表达式
Expression,抽象表达式类
public interface Expression {int interpret(Map<String, Expression> variables);}
TerminalExpression,末端表达式: 数字与变量
public class Number implements Expression {private int number;public Number(int number) {this.number = number;}public int interpret(Map<String, Expression> variables) {return number;}}public class Variable implements Expression {private String name;public Variable(String name) {this.name = name;}public int interpret(Map<String, Expression> variables) {if (null == variables.get(name))return 0;return variables.get(name).interpret(variables);}}
NonterminalExpression,非末端表达式: + -操作
public class Minus implements Expression {Expression leftOperand;Expression rightOperand;public Minus(Expression left, Expression right) {leftOperand = left;rightOperand = right;}public int interpret(Map<String, Expression> variables) {return leftOperand.interpret(variables) - rightOperand.interpret(variables);}}public class Plus implements Expression {Expression leftOperand;Expression rightOperand;public Plus(Expression left, Expression right) {leftOperand = left;rightOperand = right;}public int interpret(Map<String, Expression> variables) {return leftOperand.interpret(variables) + rightOperand.interpret(variables);}}
环境角色
public class Evaluator implements Expression {private Expression syntaxTree;public Evaluator(String expression) {Stack<Expression> expressionStack = new Stack<Expression>();for (String token : expression.split(" ")) {if (token.equals("+")) {Expression subExpression = new Plus(expressionStack.pop(), expressionStack.pop());expressionStack.push(subExpression);} else if (token.equals("-")) {Expression right = expressionStack.pop();Expression left = expressionStack.pop();Expression subExpression = new Minus(left, right);expressionStack.push(subExpression);} elseexpressionStack.push(new Variable(token));}syntaxTree = expressionStack.pop();}public int interpret(Map<String, Expression> context) {return syntaxTree.interpret(context);}}
客户端
public class InterpreterExample {public static void main(final String[] args) {final String expression = "w x z - +";final Evaluator sentence = new Evaluator(expression);final Map<String, Expression> variables = new HashMap<String, Expression>();variables.put("w", new Number(5));variables.put("x", new Number(10));variables.put("z", new Number(42));final int result = sentence.interpret(variables);System.out.println(result);}}
优点
最显著的优点就是扩展性,修改语法规则只需要修改相应的非终结符就可以了,若扩展语法,只需要增加非终结符类就可以了
缺点
- 解释器模式会引起类的膨胀,每个语法都需要产生一个非终结符表达式,语法规则比较复杂时,就可能产生大量的类文件,为维护带来非常多的麻烦
- 对于复杂的文法,构建其抽象语法树会显得异常繁琐
- 一般场景下,很少使用
Android 中的应用
类似解释器模式:PackageParser#parseBaseApkCommon、PackageParser#parseBaseApplication 解析 activity、receiver、service等标签
参考
书籍:《设计模式之禅》、《Android源码设计模式》
技术文章:
菜鸟教程-设计模式、
掘金-设计模式之解释器模式
