解释器
- 是一种不常用的设计模式
- 用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的解释器和解释器设计
- 当我们需要开发一种新的语言时,可以考虑使用解释器模式
- 尽量不要使用解释器模式,后期维护会有很大麻烦。在项目中,可以使用jruby、groovy、java的js引擎来替代解释器的作用,弥补java语言的不足。
开发中常见的场景
- EL表达式的处理
- 正则表达式解释器
- SQL语法的解释器
- 数学表达式解释器
举例代码实现
-
解析和执行数学表达式
输入"5+4*5-8/4",输出“23” - 抽象解释器接口
/**
* 抽象解释器接口
*/
public interface Expression {
int interpret(Context context);
}
- 终结符表达式
/**
* 数值表达式---终结符表达式
*/
public class NumberExpression implements Expression{
private Integer number;
public NumberExpression(Integer number) {
super();
this.number = number;
}
@Override
public int interpret(Context context) {
return number;
}
}
/**
* 运算符号表达式---终结符表达式
* symbol:
* 1:加
* 2:减
* 3:乘
* 4:除
*/
public class SymbolExpression implements Expression {
private int symbol;
public SymbolExpression(int symbol) {
super();
this.symbol = symbol;
}
@Override
public int interpret(Context context) {
return symbol;
}
}
- 非终结符表达式
/**
* 加法表达式——加法表达式也是数值表达式的一种
*/
public class AdditionExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public AdditionExpression(NumberExpression left, NumberExpression right) {
super(1);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) + right.interpret(context);
}
}
/**
* 减法表达式---减法表达式也是数值表达式的一种
*/
public class SubtractExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public SubtractExpression(NumberExpression left, NumberExpression right) {
super(2);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) - right.interpret(context);
}
}
/**
* 乘法表达式——乘法表达式也是数值表达式的一种
*/
public class MultiplicationExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public MultiplicationExpression(NumberExpression left, NumberExpression right) {
super(3);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) * right.interpret(context);
}
}
/**
* 除法表达式——除法表达式也是数值表达式的一种
*/
public class DivisionExpression extends NumberExpression{
private NumberExpression left;
private NumberExpression right;
public DivisionExpression(NumberExpression left, NumberExpression right) {
super(4);
this.left = left;
this.right = right;
}
@Override
public int interpret(Context context) {
return left.interpret(context) / right.interpret(context);
}
}
- 上下文类(context)
public class Context {
private Expression expression;
public Context(String expression) {
LinkedList<Expression> linkedList = new LinkedList<Expression>();
int num = 0;
for(int i=0;i<expression.length();i++) {
char ati;
if((ati=expression.charAt(i))>='0' && ati<='9') {
num = num*10 + (ati-'0');
}else {
Expression peek;
SymbolExpression symbol;
NumberExpression left,right;
if(!linkedList.isEmpty() && (
(peek=linkedList.peekLast()) instanceof SymbolExpression)
&& (peek.interpret(this)==3 || peek.interpret(this)==4)
){
symbol = (SymbolExpression)linkedList.pollLast();
left = (NumberExpression)linkedList.pollLast();
right = new NumberExpression(num);
if(symbol.interpret(this)==3){
linkedList.addLast(new MultiplicationExpression(left, right));
}else{
linkedList.addLast(new DivisionExpression(left, right));
}
}else{
linkedList.addLast(new NumberExpression(num));
}
SymbolExpression symbolExpression = null;
switch (ati) {
case '+':
symbolExpression = new SymbolExpression(1);
break;
case '-':
symbolExpression = new SymbolExpression(2);
break;
case '*':
symbolExpression = new SymbolExpression(3);
break;
case '/':
symbolExpression = new SymbolExpression(4);
break;
default:
break;
}
num = 0;
linkedList.addLast(symbolExpression);
}
}
Expression peek;
if(!linkedList.isEmpty() &&(
(peek=linkedList.peekLast()) instanceof SymbolExpression)
&& (peek.interpret(this)==3 || peek.interpret(this)==4)
){
Expression symbol = linkedList.pollLast();
NumberExpression left = (NumberExpression)linkedList.pollLast();
NumberExpression right = new NumberExpression(num);
if(symbol.interpret(this)==3){
linkedList.addLast(new MultiplicationExpression(left, right));
}else{
linkedList.addLast(new DivisionExpression(left, right));
}
}else{
linkedList.add(new NumberExpression(num));
}
init(linkedList);
}
private void init(LinkedList<Expression> linkedList){
SymbolExpression symbolExpression = null;
NumberExpression left = null;
while(!linkedList.isEmpty()){
Expression tempExpression = linkedList.pollFirst();
if(tempExpression instanceof SymbolExpression){
symbolExpression = (SymbolExpression)tempExpression;
}else{
if(left==null){
left = (NumberExpression)tempExpression;
}else{
NumberExpression right = (NumberExpression)tempExpression;
switch (symbolExpression.interpret(this)) {
case 1:
left = new AdditionExpression(left, right);
break;
case 2:
left = new SubtractExpression(left, right);
break;
case 3:
left = new MultiplicationExpression(left, right);
break;
case 4:
left = new DivisionExpression(left, right);
break;
default:
break;
}
}
}
}
this.expression = left;
}
public int calculate(){
return this.expression.interpret(this);
}
}
- 客户端调用
public static void main(String[] args) {
Context context = new Context("33+12*9+42/2+6/3");
int calculate = context.calculate();
System.out.println(calculate);
}
-
结果
更多设计模式学习:
设计模式(1):介绍
设计模式(2):单例模式
设计模式(3):工厂模式
设计模式(4):建造者模式
设计模式(5):原型模式
设计模式(6):桥接模式
设计模式(7):装饰器模式
设计模式(8):组合模式
设计模式(9):外观模式
设计模式(10):享元模式
设计模式(11):适配器模式
设计模式(12):代理模式
设计模式(13):模板方法模式
设计模式(14):命令模式
设计模式(15):迭代器模式
设计模式(16):观察者模式
设计模式(17):中介者模式
设计模式(18):状态模式
设计模式(19):策略模式
设计模式(20):责任链模式
设计模式(21):备忘录模式
设计模式持续更新中…