解释器模式(Interpreter)

1、概念

解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子,属于行为型模式。但其在实际的系统开发中使用的很少,因为他会引起效率、性能以及维护等问题
解释器模式

2、模式结构

  • 抽象解释器(AbstractExpression):声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称作解释操作
  • 终结符表达式(TerminalExpression):实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应
  • 非终结符表达式(NonterminalExpression):文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键
  • 环境类(Context):用来存放文法中各个终结符所对应的具体值

3、使用场景

  • 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树
  • 一些重复出现的问题可以用一种简单的语言来进行表达
  • 一个简单语法需要解释的场景

4、优缺点

优点:

  • 可扩展性比较好,灵活
  • 增加了新的解释表达式的方式
  • 易于实现文法

缺点:

  • 可利用场景比较少
  • 对于复杂的文法比较难维护
  • 解释器模式会引起类膨胀
  • 解释器模式采用递归调用方法

5、实例

定义环境类Context

public class Context {
    private Map<Expression, Integer> valueMap;

    public Context() {
        this.valueMap = new HashMap<>();
    }

    public void addValue(Expression ex, Integer value) {
        valueMap.put(ex, value);
    }

    public int getValue(Expression ex) {
        if (valueMap.containsKey(ex)) {
            return valueMap.get(ex);
        }
        return 0;
    }
}

定义抽象解释器Expression

public interface Expression {
    int interpreter(Context context);
}

定义终结符表达式TerminalExpression

public class TerminalExpression implements Expression {

    private int number;

    public TerminalExpression(int number) {
        this.number = number;
    }

    @Override
    public int interpreter(Context context) {
        return number;
    }
}

定义终结符表达式VariableExpression

public class VariableExpression implements Expression {

    @Override
    public int interpreter(Context context) {
        return context.getValue(this);
    }
}

定义非终结符表达式MinusExpression

public class MinusExpression implements Expression {
    private Expression left;
    private Expression right;

    public MinusExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpreter(Context context) {
        return left.interpreter(context) - right.interpreter(context);
    }
}

定义非终结符表达式AddExpression

public class AddExpression implements Expression {

    private Expression left;
    private Expression right;

    public AddExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpreter(Context context) {
        return left.interpreter(context) + right.interpreter(context);
    }
}

客户端使用

Context context = new Context();
VariableExpression x = new VariableExpression();
VariableExpression y = new VariableExpression();
TerminalExpression terminal = new TerminalExpression(100);
context.addValue(x, 20);
context.addValue(y, 50);
Expression expression = new AddExpression(new MinusExpression(x, y), terminal);
System.out.println("Result = " + expression.interpreter(context));

版权声明:本文为fomin_zhu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。