這是我參與8月更文挑戰的第13天,活動詳情查看:8月更文挑戰java
迎來到今天的學習,今天咱們一塊兒來學習下應用場景不多,但頗有意思的一種模式----解釋器模式。多嘮叨幾句,我本月將會對java的設計模式精講,歡迎點擊頭像,關注個人專欄,我會持續更新,加油!正則表達式
系列文章:編程
設計模式之單例模式設計模式
設計模式之工廠模式markdown
設計模式之建造者模式編程語言
設計模式之代理模式ide
設計模式之訪問者模式post
設計模式之命令者模式this
...持續更新中
話很少說,進入正題
解釋器模式(Interpreter Pattern) 提供了評估語言的語法或表達式的方式,它屬於行爲型模式。這種模式實現了一個表達式接口,該接口解釋一個特定的上下文。
咱們身邊常會遇到的,好比規則引擎、正則表達式、SQL 解析等。咱們要了解解釋器的實現原理。思考如何經過更簡潔的規則來表示複雜的邏輯。
官方是這樣定義的:用於定義語言的語法規則表示,並提供解釋器來處理句子中的語法。
我理解過來的就是自定義一些規則,而後處理相應的邏輯。能夠理解成,我來解釋該規則,處理邏輯的過程就是解釋的內容。
在編程語言中,if-else 用做條件判斷的語法,for 用於循環語句的語法標識。再好比,「我愛掘金」是一箇中文句子,咱們能夠用名詞、動詞、形容詞等語法規則來直觀地描述句子。
咱們下面看圖
上下文(Context):包含解釋器全局的信息。
抽象表達式(AbstractExpression):定義一個解釋器有哪些操做,能夠是抽象類或接口,同時說明只要繼承或實現的子節點都須要實現這些操做方法。
終結符表達式(TerminalExpression):用於解釋全部終結符表達式:(好比解析c=a+b,a和b是終結符,解析a和b的解釋器就是終結符表達式)
非終結符表達式(NonterminalExpression):用於解釋全部非終結符表達式:(好比c=a+b,「+"就是非終結符,解析「+」的解釋器就是一個非終結符表達式)
咱們用實際代碼深刻理解:
咱們建立一個邏輯與的解釋器例子。簡單來講,就是經過字符串名字來判斷表達式是否同時存在,存在則打印 true,存在一個或不存在都打印 false。在下面的代碼中,咱們會建立一個接口 Expression 和實現 Expression 接口的具體類,並定義一個終結符表達式類 TerminalExpression 做爲主解釋器,再定義非終結符表達式類,這裏 OrExpression、AndExpression 分別是處理不一樣邏輯的非終結符表達式。
//定義一個表達式
public interface Expression {
//經過字符串名字來判斷表達式是否同時存在,存在則打印 true,存在一個或不存在都打印 false。
boolean interpreter(String con);
}
//終結符表達式類
public class TerminalExpression implements Expression{
String data;
public TerminalExpression(String data) {
this.data = data;
}
@Override
public boolean interpreter(String con) {
if(con.contains(data)) {
return true;
} else {
return false;
}
}
}
//非終結符表達式類(and)
public class AndExpression implements Expression {
Expression expr1;
Expression expr2;
public AndExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
public boolean interpreter(String con) {
return expr1.interpreter(con) && expr2.interpreter(con);
}
}
//非終結符表達式類(or)
public class OrExpression implements Expression {
Expression expr1;
Expression expr2;
public OrExpression(Expression expr1, Expression expr2) {
this.expr1 = expr1;
this.expr2 = expr2;
}
public boolean interpreter(String con) {
return expr1.interpreter(con) || expr2.interpreter(con);
}
}
//調用下
public class Client {
public static void main(String[] args) {
Expression person1 = new TerminalExpression("mick");
Expression person2 = new TerminalExpression("mia");
Expression isSingle = new OrExpression(person1, person2);
Expression spike = new TerminalExpression("spike");
Expression mock = new TerminalExpression("mock");
Expression isCommitted = new AndExpression(spike, mock);
System.out.println(isSingle.interpreter("mick"));
System.out.println(isSingle.interpreter("mia"));
System.out.println(isSingle.interpreter("max"));
System.out.println(isCommitted.interpreter("mock, spike"));
System.out.println(isCommitted.interpreter("Single, mock"));
}
}
//輸出
true
true
false
true
false
複製代碼
從上面代碼中咱們能夠看到:在表達式範圍內的單詞能得到 true 的返回,沒有在表達式範圍內的單詞則會得到 false 的返回。
也就是說,表達式解釋器的解析邏輯放在了不一樣的表達式子節點中,這樣就能經過增長不一樣的節點來解析上下文。
點明主旨: 因此說,解釋器模式原理的本質就是對語法配備解釋器,經過解釋器來執行更詳細的操做。
OK 代碼部分就到這裏,解釋器模式不多使用,主要應用於 SQL 解析、符號處理引擎等場景中。因此你們只要理解就行。Spring spel表達式你們能夠看看!
我認爲該模式,易於擴展。暫時沒有發現其餘優勢
使用場景分析:
當一個語言須要解釋執行時。如 XML 文檔中<>括號表示的不一樣的節點含義。
當問題重複出現,且能夠用一種簡單的語言來進行表達時。好比,使用 if-else 來作條件判斷語句,當代碼中出現 if-else 的語句塊時都統一解釋爲條件語句而不須要每次都從新定義和解釋
感謝你的閱讀,若是你感受學到了東西,麻煩您點贊,關注。
我已經將本章收錄在專題裏,點擊下方專題,關注專欄,我會天天發表乾貨,本月我會持續輸入設計模式。
加油! 咱們下期再見!