行爲模式之解釋器模式 示例

今天覆習設計模式看到解釋器模式。想到之前我碰到過的一個問題。

問題:前後端多條件的解析。
例:某字符串token開始於“a” 且包含“b” 或長度等於10

之前是通過三方的組件解決的。如果要自己實現一個可擴展、易交互的方案。之前沒想到什麼好辦法。

其實可以用解釋器模式封裝兩層來解決。

但我的解釋器示例以另一個更簡單的例子做一個舉例。上面的僅是一個思考。

問題:波蘭表示法。運算符末尾添加操作數的方式
例:1 2 + 代表1+2的運算。 3 4 + 5 - 6 + 代表3+4-5+6的運算

解釋器一般有幾部分組成。

1、Context(環境):封裝解釋器的全局信息,所有具體的解釋器都需訪問Context.

2、AbstractExpression(抽象表達式):一個抽象類或接口。聲明執行的解釋方法,由所有具體的解釋器實現。

3、TerminalExpression(終結符表達式)。一種解釋器類,實現與語法終結符相關的操作。終結符表達式必須被實現或示例化,因爲它表示表達式的結尾

4、NonTerminalExpression(非終結符表達式):實現語法的不同規則或符號的類。每一個語法都應該創建一個類。

實現代碼示例:

1、表達式接口:

/**
 * 表達式接口
 */
public interface Expression {

    public float interpret();
}

2、終結符表達式。(在本例中爲數值)

/**
 * 數值表達式
 */
public class NumberExpression implements Expression{


    private float number;

    public NumberExpression(float number){
        this.number = number;
    }

    @Override
    public float interpret() {
        return number;
    }
}

3、非終結符表達式。本例中以加法、減法兩個規則爲例

/**
 * 操作符解釋器:加法
 */
public class PlusExpression implements Expression{


    Expression left;
    Expression right;
    public PlusExpression(Expression left, Expression right){

        this.left = left;
        this.right = right;
    }
    @Override
    public float interpret() {
        return this.left.interpret() + this.right.interpret();
    }
}
/**
 * 操作符解釋器:減法
 */
public class MinusExpression implements Expression{


    Expression left;
    Expression right;
    public MinusExpression(Expression left, Expression right){

        this.left = left;
        this.right = right;
    }
    @Override
    public float interpret() {
        return this.left.interpret() - this.right.interpret();
    }
}

4、寫一段代碼通過建立好的類來實現語法樹。

/**
 * 通過解釋器類實現語法樹
 */
public class Evaluator {

    public float evaluator(String expression){

        Stack<Expression> stack = new Stack<>();
        float result = 0;
        for (String token : expression.split(" ")){

            if(isOperator(token)){
                Expression exp = null;
                if(token.equals("+")){
                   exp = stack.push(new PlusExpression(stack.pop(), stack.pop()));
                }else if(token.equals("-")){
                   exp = stack.push(new MinusExpression(stack.pop(),stack.pop()));
                }

                if(exp != null){
                    result = exp.interpret();
                    stack.push(new NumberExpression(result));
                }
            }

            if(isNumber(token)){
                stack.push(new NumberExpression(Float.parseFloat(token)));
            }
        }
        return result;
    }

    private boolean isOperator(String token){
        if(token.equals("+") || token.equals("-"))
            return true;
        return false;
    }

    private boolean isNumber(String token){
        try {
            float v = Float.parseFloat(token);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    public static void main(String[] args) {

        Evaluator evaluator = new Evaluator();
        System.out.println(evaluator.evaluator("2 3 +"));
        System.out.println(evaluator.evaluator("2 3 + 5 - 6 +"));
    }
}

一個簡單的解釋器模式代碼完成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章