1. 程式人生 > >java設計模式------直譯器模式

java設計模式------直譯器模式

直譯器模式

  • 概述 : 給定一個語言,定義它的文法表示,並定義一個直譯器,這個直譯器使用該標識來解釋語言中的句子.

  • 使用場景 : 如果一種特定型別的問題發生的頻率足夠高,那麼可能就值得將該問題的各個例項表述為一個簡單語言中的句子.這樣就可以構建一個直譯器,該直譯器通過解釋這些句子來解決該問題.

  • 直譯器模式的結構 :

    • 抽象直譯器 : 宣告一個所有具體表達式都要實現的抽象介面(或者抽象類),介面中主要是一個interpret()方法,成為解釋操作.具體解釋任務由它的各個實現類來完成,

    • 終結符表示式 : 實現與文法中的元素相關聯的解釋操作,通常一個直譯器模式中只有一個終結符表示式

      ,但有多個例項,對應不同的終結符.終結符一半是文法中的運算單元.比如有一個簡單的公式R=R1+R2,在裡面R1和R2就是終結符,對應的解析R1和R2的直譯器就是終結符表示式.

    • 非終結符表示式 : 文法中的每條規則對應於一個非終結符表示式,非終結符表示式一般是文法中的運算子或者其他關鍵字,比如公式R=R1+R2中,”+"就是非終結符,解析”+”的直譯器就是一個非終結符表示式.非終結符表示式根據邏輯的複雜程度而增加,原則上每個問法規則都對應一個非終結符表示式.

    • 環境角色 : 這個角色的任務一般是用來存放文法中各個終結符所對應的具體值,比如R=R1+R2,我們給R1賦值1,給R2賦值2,這些資訊需要存放到環境角色.

  • 優點:

    • 可擴充套件性比較好,靈活

    • 增加了新的解釋表示式的方式

    • 易於實現簡單文法

  • 缺點:

    • 可利用場景比較小

    • 對於複雜的文法比較難維護

    • 直譯器模式會引起類膨脹

程式碼實現

     示例 : 利用直譯器完成100-(1+1)的表示式.

抽象直譯器介面 

package InterpreterPattern;
 
/**
 * Created by looper on 2017/9/7.
 */
public interface Interpreter {
  public int interpret(Context context);
}

非終結表示式類(+)

package InterpreterPattern;
 
/**
 * Created by looper on 2017/9/7.
 */
public class Add implements Interpreter{
  @Override
  public int interpret(Context context) {
    //兩數相加
    return context.getNum1() + context.getNum2();
  }
}

非終結表示式類(-)

package InterpreterPattern;
 
/**
 * Created by looper on 2017/9/7.
 */
public class Subtract implements Interpreter {
  @Override
  public int interpret(Context context) {
    //兩數相減
    return context.getNum1() - context.getNum2();
  }
}

終結符表示式類

package InterpreterPattern;
 
/**
 * Created by looper on 2017/9/7.
 */
public class Context {
  private int num1;
  private int num2;
 
  public Context(int num1,int num2){
    this.setNum1(num1);
    this.setNum2(num2);
  }
 
  public int getNum1() {
    return num1;
  }
 
  public void setNum1(int num1) {
    this.num1 = num1;
  }
 
  public int getNum2() {
    return num2;
  }
 
  public void setNum2(int num2) {
    this.num2 = num2;
  }
}

測試類

package InterpreterPattern;
 
/**
 * Created by looper on 2017/9/7.
 */
public class InterpreterPatternTest {
  public static void main(String[] args) {
    //完成100 - (1+1) 算式
    int result = new Subtract().interpret(new Context(100,new Add().interpret(new Context(1,1))));
    System.out.println("result = "+result);
  }
}