天天看點

行為型模式-11解釋器模式

文章目錄

    • 十一、解釋器模式
      • 1. `定義`
      • 2. `結構`
      • 3. `案例`
      • 4. `代碼`
      • 5. `優缺點`
      • 6. `使用場景`

十一、解釋器模式

1.

定義

  • 給定一個語言,定義它的文法表示,并定義一個解釋器,這個解釋器使用該辨別來解釋語言中的句子。

2.

結構

  • 抽象表達式角色:定義解釋器的接口,約定解釋器的解釋操作,主要包含解釋方法 interpret()。
  • 終結符表達式角色:是抽象表達式的子類,用來實作文法中與終結 符相關的操作,文法中的每一個終結符都有一個具體終結表達式與之相對應。
  • 非終結符表達式角色:也是抽象表達式的子類,用來實作文法 中與非終結符相關的操作,文法中的每條規則都對應于一個非終結符表達式。
  • 環境角色:通常包含各個解釋器需要的資料或是公共的功能,一般用來傳遞被所有 解釋器共享的資料,後面的解釋器可以從這裡擷取這些值。
  • 用戶端:主要任務是将需要分析的句子或表達式轉換成使用解釋器對象描述的抽象語 法樹,然後調用解釋器的解釋方法,當然也可以通過環境角色間接通路解釋器的解釋方法。

3.

案例

  • 加減文本運算
  • UML
行為型模式-11解釋器模式

4.

代碼

  • AbsExpression
/**
 * 抽象表達式類
 */
public abstract class AbsExpression {
    public abstract int interpret(Context context);
}
           
  • Context
/**
 *  環境角色類
 */
public class Context {
    //定義map集合,存儲變量和對應的值
    private Map<Variable,Integer> map = new HashMap<>();
    //添加變量的方法
    public void addVar(Variable var,Integer value){
        map.put(var,value);
    }
    public int getValue(Variable var){
        return map.get(var);
    }
}
           
  • Variable
/**
 * 封裝變量的類
 */
public class Variable extends AbsExpression{
    //聲明存儲變量名的成員變量
    private String name;
    public Variable(String name){
        this.name = name;
    }
    public int interpret(Context context){
        //傳回變量的值
        return context.getValue(this);
    }

    @Override
    public String toString() {
        return name;
    }
}
           
  • Minus
/**
 * 減法表達式類
 */
public class Minus extends AbsExpression{
    //減号左邊的表達式
    private AbsExpression left;
    //減号右邊的表達式
    private AbsExpression right;

    public Minus(AbsExpression left, AbsExpression right) {
        this.left = left;
        this.right = right;
    }

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

    @Override
    public String toString() {
        return "(" + left.toString() + " - " + right.toString() + ")";
    }
}
           
  • Plus
/**
 * 加法表達式類
 */
public class Plus extends AbsExpression {

    //+号左邊的表達式
    private AbsExpression left;
    //+号右邊的表達式
    private AbsExpression right;

    public Plus(AbsExpression left, AbsExpression right) {
        this.left = left;
        this.right = right;
    }

    public int interpret(Context context) {
        //将左邊表達式的結果和右邊表達式的結果進行相加
        return left.interpret(context) + right.interpret(context);
    }

    @Override
    public String toString() {
        return "(" + left.toString() + " + " + right.toString() + ")";
    }
}
           
  • 測試類
public class Client {
    public static void main(String[] args) {
        //建立環境對象
        Context context = new Context();

        //建立多個變量對象
        Variable v1 = new Variable("a");
        Variable v2 = new Variable("b");
        Variable v3 = new Variable("c");
        Variable v4 = new Variable("d");

        //将變量存儲到環境對象中
        context.addVar(v1,2);
        context.addVar(v2,3);
        context.addVar(v3,4);
        context.addVar(v4,5);
        AbsExpression expression = new Minus(v1,new Minus(new Minus(v2,v3),v4));
        //解釋:計算
        int rs = expression.interpret(context);
        System.out.println(expression+"="+rs);
        System.out.println("(2 - ((3 - 4) - 5))=8");
    }
}
//測試結果
//(a - ((b - c) - d))=8
//(2 - ((3 - 4) - 5))=8
           

5.

優缺點

  • 優點

    • 易于改變和擴充方法
    • 實作文法較為容易
    • 增加新餓解釋表達式較為友善
  • 缺點

    • 執行效率低

6.

使用場景

  • 當問題重複出現,且可以用一種簡單的語言來進行表達時
  • 當語言的文法較為簡單,執行效率不是關鍵問題時