解釋器模式

描述:對一個表達式進行解釋時,將表達式分爲終結符、非終結符、運算環境,這樣區分能夠把表達式的各個部分獨立出來擴展。java

名稱解釋:ide

  1. 表達式:一條運算語句,如c = a + b,它有一個解釋方法,能夠計算表達式結果
  2. 終結符:表達式中的變量,如a、b,終結符表達式負責解釋終結符,即計算結果
  3. 非終結符:表達式中的運算符,如+,非終結符表達式負責計算非終結符的結果
  4. 運算環境:負責給終結符賦值,如a=1

場景:寫個解釋器,解釋a+b=3,其中a=1,b=2,c=0,另外擴展一個相反數運算使-a=-1。this

實現:code

抽象一個表達式,負責解釋終結符或者非終結符,其定義一個解釋方法,計算表達式的值,同時覆蓋equals和hashCode方法,方便判斷兩個表達式是否相同orm

abstract class Expression {
    String name;
    Expression(String name) {
        this.name = name;
    }
    abstract int interpret(Context ctx);
    @Override
    public boolean equals(Object obj) {
        if(null == obj) {
            return false;
        }
        if(obj instanceof String && name.equals(obj)) {
            return true;
        }
        return false;
    }
    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

定義一個終結符表達式,也就是負責計算變量的值get

class Variable extends Expression {
    Variable(String name) {
        super(name);
    }
    @Override
    int interpret(Context ctx) {
        return ctx.lookup(this);
    }
}

定一個非終結符表達式,其名爲加法,負責計算兩個終結符的值hash

class AddExpression extends Expression {
    Expression var1;
    Expression var2;
    AddExpression(Expression var1, String name, Expression var2) {
        super(name);
        this.var1 = var1;
        this.var2 = var2;
    }
    @Override
    int interpret(Context ctx) {
        return var1.interpret(ctx) + var2.interpret(ctx);
    }
}

若是想擴展一種運算,能夠直接定義一個非終結符表達式,好比定義一個求相反數的運算it

//一個數的相反數
class OppositeExpression extends Expression {
    Expression var;
    OppositeExpression(String name, Expression var) {
        super(name);
        this.var = var;
    }
    @Override
    int interpret(Context ctx) {
        return -var.interpret(ctx);
    }
}

定義一個運算環境,用於給變量賦值io

class Context {
    Map<Expression, Integer> map = new HashMap<Expression, Integer>();
    void assign(Expression var, int value) {
        map.put(var, value);
    } 
    int lookup(Expression var) {
        Object obj = map.get(var);
        if(null == obj) {
            // 若是變量未初始化,默認是0
            return 0;
        }
        return (Integer) obj;
    }
}

客戶端調用:form

public static void main(String[] args) {
    Context ctx = new Context();
    Variable a = new Variable("a");
    Variable b = new Variable("b");
    Variable c = new Variable("c"); // 不初始化,默認爲0
    ctx.assign(a, 1);
    ctx.assign(b, 2);
    System.out.println("a = " + a.interpret(ctx));
    System.out.println("b = " + b.interpret(ctx));
    System.out.println("c = " + c.interpret(ctx));
    // 相反數運算
    OppositeExpression opposite = new OppositeExpression("-", a);
    int rs = opposite.interpret(ctx);
    String exp = String.format("%s%s = %d", opposite.name, a.name, rs);
    System.out.println(exp);
    // 加運算
    AddExpression add = new AddExpression(a, "+", b);
    rs = add.interpret(ctx);
    exp = String.format("%s %s %s = %d", a.name, add.name, b.name, rs);
    System.out.println(exp);
}

結果:

a = 1 b = 2 c = 0 -a = -1 a + b = 3

相關文章
相關標籤/搜索