直譯器模式(Interpreter)

jdon發表於2019-07-17

1、概念

直譯器模式給定一個語言,定義它的文法的一種表示,並定義一個直譯器,該直譯器使用該表示來解釋語言中的句子,屬於行為型模式。但其在實際的系統開發中使用的很少,因為他會引起效率、效能以及維護等問題


2522282-003bccf78135adcf.jpg
直譯器模式

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));

相關文章