#一、解釋器模式介紹 ##1、定義與類型 定義:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。 為瞭解釋一種語言,而為語言創建的解釋器 類型:行為型 #2、適用場景 某個特定類型問題發生頻率足夠高 ##3、優點 語法由很多類表示,容易改變及擴展此“語 ...
一、解釋器模式介紹
1、定義與類型
定義:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
為瞭解釋一種語言,而為語言創建的解釋器
類型:行為型
2、適用場景
某個特定類型問題發生頻率足夠高
3、優點
語法由很多類表示,容易改變及擴展此“語言"
4、缺點
當語法規則數目太多時,增加了系統複雜度
5、相關設計模式
解釋器模式和適配器模式
適配器模式是需要預先知道要適配的規則,解釋器則是要把規則寫好,根據規則執行解釋
二、代碼示例
模擬場景:模擬電腦解釋計算表達式,例如中綴表達式 6 * (100 +11) ,電腦會先轉換為尾碼運算符 6 100 11 + * ,轉換過程此處省略,再依次入棧,遇到運算符則出棧中的兩個數字進行計算,再將計算結果入棧。
此處需要補充知識點:電腦如何計算我們的表達式的,可參考https://wenku.baidu.com/view/3ff189a15ef7ba0d4a733bb5.html中的表達式求值
解釋器介面:
public interface Interpreter {
int interpret();
}
數字解釋器:
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 "+";
}
}
乘法解釋器:
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
三、源碼示例
1、JDK中的正則Pattern
2、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