一、解釋器模式介紹
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/6016.html
標籤:設計模式
