1. 定义
- 通过定义一个表达式接口,解释特定的上下文.
- 本质:将复杂的问题简单化,模块化,分离实现,解释执行
2. 使用场景
- 如果某个简单的语言需要解释执行而且可以将该语言中的语句表示为一个抽象的语法树时
- 某些特性的领域出现不断重复的问题时,可以将该领域的问题转化为语法规则下的语句,然后构建解释器来解释该语句,例如英文的大小写转换
3. 优缺点
- 优点:
- 灵活的扩展性,扩展延伸时只需增加新的解释器
- 易于实现的文法
- 缺点:
- 生成的大量类可能造成后期维护困难;
- 对于复杂的文法构建其抽象语法树会异常繁琐
- 可利用场景比较少
4. Android源码中的使用
- 项目中 AndroidManifest.xml 这个配置文件的解释(PackageParser)
- 布局文件等xml文件最终都会被解析成java类的对象
- 开发中经常会用到json或xml格式的数据,并对其进行解析
5. 实例演示
以对算术表达式的解释为例
- 首先构建一个解释器的抽象基类
abstract class ArithmeticExpression {
public abstract int interpret();
}
- 表达式中数字的解析类
//数字解释器
class NumExpression extends ArithmeticExpression {
private int num;
public NumExpression(int num) {
this.num = num;
}
@Override
public int interpret() {
return num;
}
}
- 运算符号解释器的基类
abstract class OperatorExpression extends ArithmeticExpression {
//声明两个变量存储运算符号两边的数字解释器
protected ArithmeticExpression exp1, exp2;
public OperatorExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {
this.exp1 = exp1;
this.exp2 = exp2;
}
}
- 创建加法,减法运算符的解释器类
//加法运算解释器
class AdditionExpression extends OperatorExpression {
public AdditionExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {
super(exp1, exp2);
}
@Override
public int interpret() {
return exp1.interpret() + exp2.interpret();
}
}
//减法解释器
class SubtractionExpression extends OperatorExpression {
public SubtractionExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {
super(exp1, exp2);
}
@Override
public int interpret() {
return exp1.interpret() - exp2.interpret();
}
}
- 真正处理业务的类,使用上面的解释器对表达式进行解析
//处理与解释相关的业务
class Calculator {
//声明一个stack栈存储并操作相关的解释器
private Stack<ArithmeticExpression> mExpStack = new Stack<>();
public Calculator(String expression) {
//存储运算符两边的数字解释器
ArithmeticExpression exp1, exp2;
//空格分隔表达式字符串
String[] elements = expression.split(" ");
for (int i = 0; i < elements.length; i++) {
switch (elements[i].charAt(0)) {
case '+'://如果是加号
exp1 = mExpStack.pop();//将栈中的解释器弹出作为运算符号左边的解释器
exp2 = new NumExpression(Integer.valueOf(elements[++i]));
mExpStack.push(new AdditionExpression(exp1, exp2));
break;
case '-':
exp1 = mExpStack.pop();
exp2 = new NumExpression(Integer.valueOf(elements[++i]));
mExpStack.push(new SubtractionExpression(exp1, exp2));
break;
default:
mExpStack.push(new NumExpression(Integer.valueOf(elements[i])));
break;
}
}
}
//计算结果
public int calculate() {
return mExpStack.pop().interpret();
}
}
- 真正的去解析一个表达式
private void methodInterpreterPattern() {
//以对算术表达式的解释为例
String expression = "123 + 10 + 100 + 100 + 3000 - 1000 - 111";
Calculator calculator = new Calculator(expression);
String info = expression + " 的计算结果是: " + calculator.calculate();
LjyLogUtil.i(info);
}
- 当需要扩展,如增加乘法,除法,括号等运算符时,只需要实现对应的解释器类,并修改Calculator类中的逻辑即可
网友评论