解释器模式是一种用得比较少的行为型模式.提供了一种解释语言的语法或表达式的方式.
通过定义一个表达式接口,解释一个特定的上下文.
给定一个语言,解释器模式可以定义出其文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子.
解释器中涉及到的文法,就是符合一定规则的语句结构.
如 abcd…….cdef(ab开头,ef结尾,中间N个cd)中,根据N值的不同,可以得到不同的字符串如,abef,abcdef,abcdcdef….
假设我们有如下推导式
S ::= abA*ef
A ::= cd
其中::=
表示推导,*
表示闭包,意思是A可以有0~N
个重复,S是初始符号,abef和cd是终结符号.
像这样的从一个具体的符号出发,通过不断地应用一些产生式规则 从而生成一个字符串的集合,我们将描述这个集合的文法称为形式文法.
给定一个语言(如由abcdef六个字符组成的字符串集合),定义它的文法的一种表示(S::=abA*ef,A::=cd)并定义一个解释器,解释器使用该表示来解释语言中的句子.
其中的解释器类似一个翻译机
其中涉及到的角色有:
AbstractExpression: 抽象表达式,声明一个抽象的解释操作父类,定义一个抽象的解释方法,具体的实现由子类解释器完成/
TerminalExpression: 终结符表达式,实现文法中与终结符有关的解释操作,文法中每一个终结符都有一个具体的终结表达式与之对应
NonterminalExpression: 非终结符表达式,实现文法中与非终结符有关的解释操作
Context: 上下文环境类,包含解释器之外的全局信息
Client: 客户端,解析表达式,构建抽象语法树,执行具体的解释操作等.
如下我们通过对算术表达式的解释来看一个解释器模式的实现,
如表达式m+n+p
中,如果我们使用解释器模式对该表达式进行解释,那么m,n,p
代表的三个字母可以看成是终结符号,而+
代表的运算符则可以看成是非终结符号
public abstract class ArithmeticExpression {
public abstract int interptet();
}
解释器中定义了interptet()方法,ArithmeticExpression有两个直接子类,NumExpression,和OperatorExpression
public class NumExpression extends ArithmeticExpression {
private int num;
public NumExpression(int _num) {
num = _num;
}
@Override public int interptet() {
return num;
}
}
public abstract class OperatorExpression extends ArithmeticExpression {
protected ArithmeticExpression mArithmeticExpression1,mArithmeticExpression2;
public OperatorExpression(ArithmeticExpression _arithmeticExpression1,
ArithmeticExpression _arithmeticExpression2) {
mArithmeticExpression1 = _arithmeticExpression1;
mArithmeticExpression2 = _arithmeticExpression2;
}
}
public class AdditionExpression extends OperatorExpression {
public AdditionExpression(ArithmeticExpression _arithmeticExpression1,
ArithmeticExpression _arithmeticExpression2) {
super(_arithmeticExpression1, _arithmeticExpression2);
}
@Override public int interptet() {
return mArithmeticExpression1.interptet() + mArithmeticExpression2.interptet();
}
}
public class Calculator {
protected Stack mArithmeticExpressionStack = new Stack<>();
public Calculator(String expression) {
ArithmeticExpression arithmeticExpression1, arithmeticExpression2;
String[] elements = expression.split(" ");
for (int i = 0; i < elements.length; ++i) {
switch (elements[i].charAt(0)) {
case '+':
arithmeticExpression1 = mArithmeticExpressionStack.pop();
arithmeticExpression2 = new NumExpression(Integer.valueOf(elements[++i]));
mArithmeticExpressionStack.push(
new AdditionExpression(arithmeticExpression1, arithmeticExpression2));
break;
default:
mArithmeticExpressionStack.push(new NumExpression(Integer.valueOf(elements[i])));
break;
}
}
}
public int calculate() {
return mArithmeticExpressionStack.pop().interptet();
}
}
// 解释计算123+124+125+126的运算结果
Calculator calculator = new Calculator("123+124+125+126");
Log.d(TAG, "setBtnClick: -->" + calculator.calculate());
DesignPatterns