本文源碼:GitHub·點這裏 || GitEE·點這裏git
解釋器模式是對象的行爲模式。給定一個語言以後,解釋器模式能夠定義出其文法的一種表示,並同時提供一個解釋器。客戶端可使用這個解釋器來解釋這個語言中的表達式。github
(1)、抽象表達式正則表達式
Express:聲明具體表達式角色須要實現的抽象接口,該接口主要提供一個interpret()方法,稱作解釋操做。spring
(2)、終結符表達式express
TerminalExpress:實現抽象表達式角色接口,主要是一個interpret()方法;每一個終結符都有一個具體終結表達式與之相對應。好比解析c=a+b,a和b是終結符,解析a和b的解釋器就是終結符表達式。框架
(3)、非終結符表達式ide
NotTerminalExpress:每一條規則都須要一個具體的非終結符表達式用來銜接,通常是指運算符或者邏輯判斷,好比c=a+b,「+"就是非終結符,解析「+」的解釋器就是一個非終結符表達式。this
(4)、環境容器lua
DataMap:通常是用來存放各個終結符所對應的具體值,好比c=a+b轉換爲c=1+2。這些信息須要一個存放環境。調試
public class C01_InScene { public static void main(String[] args) { DataMap dataMap = new DataMap(); TerminalExpress terminalExpress1 = new TerminalExpress("num1"); TerminalExpress terminalExpress2 = new TerminalExpress("num2"); TerminalExpress terminalExpress3 = new TerminalExpress("num3"); dataMap.putData(terminalExpress1, 1); dataMap.putData(terminalExpress2, 2); dataMap.putData(terminalExpress3, 3); // 1+2-3 = 0 System.out.println(new Minus( new Add(terminalExpress1,terminalExpress2), terminalExpress3) .interpret(dataMap)); } } // 解釋器接口 interface Express { Integer interpret(DataMap dataMap) ; } // 非終結符表達式 abstract class NotTerminalExpress implements Express { Express express1,express2; public NotTerminalExpress(Express express1, Express express2){ this.express1 = express1; this.express2 = express2; } } // 終結符表達式: 1+2 終結符: 1 和 2 class TerminalExpress implements Express { public String field ; public TerminalExpress (String field){ this.field = field ; } @Override public Integer interpret(DataMap dataMap) { return dataMap.getData(this); } } // 加法表達式 class Add extends NotTerminalExpress { public Add (Express e1, Express e2) { super(e1, e2); } // 將兩個表達式相減 @Override public Integer interpret(DataMap context) { return this.express1.interpret(context) + this.express2.interpret(context); } } // 減法表達式 class Minus extends NotTerminalExpress { public Minus (Express e1, Express e2) { super(e1, e2); } // 將兩個表達式相減 @Override public Integer interpret(DataMap context) { return this.express1.interpret(context) - this.express2.interpret(context); } } // 數據容器 class DataMap { private Map<Express,Integer> dataMap = new HashMap<>() ; public void putData (Express key,Integer value){ dataMap.put(key,value) ; } public Integer getData (Express key){ return dataMap.get(key) ; } }
import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; public class SpringTest { public static void main(String[] args) { SpelExpressionParser parser = new SpelExpressionParser () ; Expression expression = parser.parseExpression("(1+3-2)*3") ; Integer result = (Integer)expression.getValue() ; System.out.println("result="+result); } }
(1)Expression結構
表達式接口:具備不一樣的實現類。
interface Expression class CompositeStringExpression implements Expression class LiteralExpression implements Expression class SpelExpression implements Expression
核心方法:
Object getValue() throws EvaluationException;
(2)SpelExpressionParser結構
SpelExpressionParser extends TemplateAwareExpressionParser TemplateAwareExpressionParser implements ExpressionParser interface ExpressionParser
(3)ExpressionParser接口
public interface ExpressionParser { Expression parseExpression(String var1) ; Expression parseExpression(String var1, ParserContext var2) ; }
(4)Expression獲取
根據不一樣的條件獲取不一樣的Expression對象。這裏產生類的依賴關係。
源碼位置:TemplateAwareExpressionParser
public Expression parseExpression(String expressionString, ParserContext context) throws ParseException { if (context == null) { context = NON_TEMPLATE_PARSER_CONTEXT; } return context.isTemplate() ? this.parseTemplate(expressionString, context) : this.doParseExpression(expressionString, context); }
編譯器、運算符表達式、正則表達式、機器人等。
當有一個表達式或者語言須要解釋執行,該場景下的內容能夠考慮使用解釋器模式,使程序具備良好的擴展性。
解釋器模式會引發類膨脹,會致使程序執行和調試很是複雜,不容易理解。
GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent