本文源碼:GitHub·點(diǎn)這里 || GitEE·點(diǎn)這里
創(chuàng)新互聯(lián)公司專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、安康網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5建站、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為安康等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
解釋器模式是對象的行為模式。給定一個語言之后,解釋器模式可以定義出其文法的一種表示,并同時提供一個解釋器??蛻舳丝梢允褂眠@個解釋器來解釋這個語言中的表達(dá)式。
(1)、抽象表達(dá)式
Express:聲明具體表達(dá)式角色需要實現(xiàn)的抽象接口,該接口主要提供一個interpret()方法,稱做解釋操作。
(2)、終結(jié)符表達(dá)式
TerminalExpress:實現(xiàn)抽象表達(dá)式角色接口,主要是一個interpret()方法;每個終結(jié)符都有一個具體終結(jié)表達(dá)式與之相對應(yīng)。比如解析c=a+b,a和b是終結(jié)符,解析a和b的解釋器就是終結(jié)符表達(dá)式。
(3)、非終結(jié)符表達(dá)式
NotTerminalExpress:每一條規(guī)則都需要一個具體的非終結(jié)符表達(dá)式用來銜接,一般是指運(yùn)算符或者邏輯判斷,比如c=a+b,“+"就是非終結(jié)符,解析“+”的解釋器就是一個非終結(jié)符表達(dá)式。
(4)、環(huán)境容器
DataMap:一般是用來存放各個終結(jié)符所對應(yīng)的具體值,比如c=a+b轉(zhuǎn)換為c=1+2。這些信息需要一個存放環(huán)境。
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) ;
}
// 非終結(jié)符表達(dá)式
abstract class NotTerminalExpress implements Express {
Express express1,express2;
public NotTerminalExpress(Express express1, Express express2){
this.express1 = express1;
this.express2 = express2;
}
}
// 終結(jié)符表達(dá)式: 1+2 終結(jié)符: 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);
}
}
// 加法表達(dá)式
class Add extends NotTerminalExpress {
public Add (Express e1, Express e2) {
super(e1, e2);
}
// 將兩個表達(dá)式相減
@Override
public Integer interpret(DataMap context) {
return this.express1.interpret(context) + this.express2.interpret(context);
}
}
// 減法表達(dá)式
class Minus extends NotTerminalExpress {
public Minus (Express e1, Express e2) {
super(e1, e2);
}
// 將兩個表達(dá)式相減
@Override
public Integer interpret(DataMap context) {
return this.express1.interpret(context) - this.express2.interpret(context);
}
}
// 數(shù)據(jù)容器
class DataMap {
private Map 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結(jié)構(gòu)
表達(dá)式接口:具有不同的實現(xiàn)類。
interface Expression
class CompositeStringExpression implements Expression
class LiteralExpression implements Expression
class SpelExpression implements Expression
核心方法:
Object getValue() throws EvaluationException;
(2)SpelExpressionParser結(jié)構(gòu)
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獲取
根據(jù)不同的條件獲取不同的Expression對象。這里產(chǎn)生類的依賴關(guān)系。
源碼位置: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);
}
編譯器、運(yùn)算符表達(dá)式、正則表達(dá)式、機(jī)器人等。
當(dāng)有一個表達(dá)式或者語言需要解釋執(zhí)行,該場景下的內(nèi)容可以考慮使用解釋器模式,使程序具有良好的擴(kuò)展性。
解釋器模式會引起類膨脹,會導(dǎo)致程序執(zhí)行和調(diào)試非常復(fù)雜,不容易理解。
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent