设计模式(15)--解释器模式

时间:2022-05-28 14:24:14

解释器模式,还是从名字引定义吧,解释器,解释东西,解释什么?解释我们自定义的语言(或功能)。

举个栗子:咱是个java程序员,在写某个应用程序的时候发现经常需要处理“1-2+3-45+56-90”,这样的字符串,经常进行类型转化,逻辑处理太麻烦(当然,这样简单处理的我们自己写个方法就处理了,还通用,但是如果不只处理+-呢,如果要求能扩展呢,我们的硬编码方法就不合适了),我们想个解决办法,我们把种字符串类加减法当成我们自己设计的一种微型语言,我们自己给他设计一个解析器,专门用来解析处理这种字符串。


使用形式语言表示该文法规则:

表达式(expression):值(value) |  操作符(operation)

操作符operation):表达式(expression)+表达式(expression)|表达式(expression)-表达式(expression)

值(value) :整数

解释器模式UML类图:

设计模式(15)--解释器模式

表达式子类和AbstractExpression既是继承关系,又有聚合关系,看实例代码就能看出来。

相关示例代码:

抽象表达式类:

/****
* 抽象表达式类
* @author wjw
*
*/
public abstract class AbstractExpression {

public abstract int interpret();
}

加法表达式:

/*****
* 加法表达式
* @author wjw
*
*/
public class AddExpression extends AbstractExpression{
private AbstractExpression left;
private AbstractExpression right;

public AddExpression(AbstractExpression left, AbstractExpression right){
this.left = left;
this.right = right;
}
@Override
public int interpret() {
// TODO Auto-generated method stub
return left.interpret() + right.interpret();
}

}

减法表达式:


/*****
* 减法表达式
* @author wjw
*
*/
public class SubtractionExpression extends AbstractExpression{
private AbstractExpression left;
private AbstractExpression right;

public SubtractionExpression(AbstractExpression left, AbstractExpression right){
this.left = left;
this.right = right;
}
@Override
public int interpret() {
// TODO Auto-generated method stub
return left.interpret() - right.interpret();
}

}

值表达式:

public class ValueExpression extends AbstractExpression{
private String value;


public ValueExpression(String value){
this.value = value;

}
@Override
public int interpret() {
// TODO Auto-generated method stub
return Integer.parseInt(value);
}

}

指令处理类:

/*****
* 指令处理类,用来接收指令,进行处理
* @author wjw
*
*/
public class InstructionHandler {

private AbstractExpression se;
public int handle(String expression){
Stack<AbstractExpression> stack = new Stack<AbstractExpression>();
String[] expressionArray = expression.split(" ");
for (int i = 0; i < expressionArray.length; i++) {
//System.out.println(expressionArray[i]);
if("+".equals(expressionArray[i])){
//加号减号表达式
AbstractExpression right = new ValueExpression(expressionArray[++i]);

AbstractExpression aeAdd = new AddExpression(stack.pop(), right);
stack.push(aeAdd);
}else if("-".equals(expressionArray[i])){
//值表达式
AbstractExpression right = new ValueExpression(expressionArray[++i]);
AbstractExpression aeSub = new SubtractionExpression(stack.pop(), right);
stack.push(aeSub);
}else{
AbstractExpression value = new ValueExpression(expressionArray[i]);
stack.push(value);
}
}

return stack.pop().interpret();

}
}


Main类:

public class Main {

public static void main(String[] args) {
String expression = "2 + 3 - 5 + 9 + 3 + 4 - 2 + 4";
InstructionHandler ih = new InstructionHandler();
int result = ih.handle(expression);

System.out.println("结算结果为:" + result);
}
}

运行结果:

结算结果为:18


说明:编程语言就得有编程语言的规则,我们使用JAVA写程序的时候写错了都不能正确编译,而我们这个微型小程序的语法就是 数字 操作符都用空格隔开,虽然是微型语言,咱也有大语言的气魄,写错,也不给你正确执行。

该解释器模式根据文法规则定义了一个抽象表达式类,三个具体表达式类,一个指令处理类。在文法规则的指导下,完成了这个示例程序的简单代码。

执行原理:指令处理类中,利用栈来分析传进来的字符串,表达式是数字类字符串,先放进栈中,表达式是操作符,再将栈中数字取出来,和操作符右边组成一个AddExpression或SubtractionExpression,最后经过层层组合,组合成一个总的Expression。所以我们写解释器模式的目的就是将我们处理不了的语句解释成我们可以处理的Expression,随后执行这个我们可以处理的Expression,返回结果。

解释器模式说明:

就是将我们自定义语言中不可被识别执行的语句解释为可以被执行的表达式。


如有错误,欢迎指正

end