解釋器模式

1、解釋器模式介紹

一、定義與類型

定義:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
爲了解釋一種語言,而爲語言建立的解釋器
類型:行爲型html

二、適用場景

某個特定類型問題發生頻率足夠高spring

三、優勢

語法由不少類表示,容易改變及擴展此「語言"express

四、缺點

當語法規則數目太多時,增長了系統複雜度設計模式

五、相關設計模式

解釋器模式和適配器模式
適配器模式是須要預先知道要適配的規則,解釋器則是要把規則寫好,根據規則執行解釋ide

2、代碼示例

模擬場景:模擬計算機解釋計算表達式,例如中綴表達式 6 * (100 +11) ,計算機會先轉換爲後綴運算符 6 100 11 + * ,轉換過程此處省略,再依次入棧,遇到運算符則出棧中的兩個數字進行計算,再將計算結果入棧。
此處須要補充知識點:計算機如何計算咱們的表達式的,可參考https://wenku.baidu.com/view/3ff189a15ef7ba0d4a733bb5.html中的表達式求值工具

解釋器接口:測試

public interface Interpreter {
    int interpret();
}

數字解釋器:this

public class NumberInterpreter implements Interpreter {
    private int number;

    public NumberInterpreter(int number) {
        this.number = number;
    }

    public NumberInterpreter(String number) {
        this.number = Integer.valueOf(number);
    }

    @Override
    public int interpret() {
        return this.number;
    }
}

加法解釋器:設計

public class AddInterpreter implements Interpreter {
    private Interpreter firstExpression, secondExpression;

    public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return this.firstExpression.interpret() + this.secondExpression.interpret();
    }

    @Override
    public String toString() {
        return "+";
    }
}

乘法解釋器:code

public class MultiInterpreter implements Interpreter {
    private Interpreter firstExpression, secondExpression;

    public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
        this.firstExpression = firstExpression;
        this.secondExpression = secondExpression;
    }

    @Override
    public int interpret() {
        return this.firstExpression.interpret() * this.secondExpression.interpret();
    }

    @Override
    public String toString() {
        return "*";
    }
}

運算符工具類:

public class OperatorUtil {
    public static boolean isOperator(String symbol) {
        return (symbol.equals("+") || symbol.equals("*"));
    }

    public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
        if (symbol.equals("+")) {
            return new AddInterpreter(firstExpression, secondExpression);
        } else if (symbol.equals("*")) {
            return new MultiInterpreter(firstExpression, secondExpression);
        }
        return null;
    }
}

轉換器類:

public class MyExpressionParser {
    private Stack<Interpreter> stack = new Stack<Interpreter>();

    public int parser(String str) {
        String[] strItemArray = str.split(" ");
        for (String symbol : strItemArray) {
            if (!OperatorUtil.isOperator(symbol)) {
                Interpreter numberExpression = new NumberInterpreter(symbol);
                stack.push(numberExpression);
                System.out.println(String.format("入棧:%d", numberExpression.interpret()));
            } else {
                // 是運算符,能夠計算
                Interpreter firstExpression = stack.pop();
                Interpreter secondExpression = stack.pop();
                System.out.println(String.format("出棧:%d 和 %d", firstExpression.interpret(), secondExpression.interpret()));
                Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, symbol);
                System.out.println(String.format("應用運算符:%s", operator));
                int result = operator.interpret();
                NumberInterpreter resultExpression = new NumberInterpreter(result);
                stack.push(resultExpression);
                System.out.println(String.format("階段結果入棧:%d", resultExpression.interpret()));
            }
        }
        int result = stack.pop().interpret();
        return result;
    }
}

測試類:

public class Test {
    public static void main(String[] args) {
        String inputStr = "6 100 11 + *";
        MyExpressionParser expressionParser = new MyExpressionParser();
        int result = expressionParser.parser(inputStr);
        System.out.println(result);
    }
}

輸出:
入棧:6
入棧:100
入棧:11
出棧:11 和 100
應用運算符:+
階段結果入棧:111
出棧:111 和 6
應用運算符:*
階段結果入棧:666
666

3、源碼示例

一、JDK中的正則Pattern

二、spring中的El表達式

測試:

public class SpringTest {
    public static void main(String[] args) {
        org.springframework.expression.ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression("6 * (100 + 11)");
        int result = (Integer) expression.getValue();
        System.out.println(result);
    }
}

輸出:666

相關文章
相關標籤/搜索