Java設(shè)計模式之解釋器模式
解釋器模式字面意思,也即解釋某些內(nèi)容的含義。這種設(shè)計模式是實際開發(fā)中最不容易用到的。比如SQL解析,符號處理引擎,會用到解釋器模式,屬于更底層的開發(fā)人員才會用到的設(shè)計模式。
本文就以解釋器模式的概念、角色和簡單的例子說明解釋器模式,讀者對這部分內(nèi)容了解即可。
一、概念
解釋器模式是指給定一門語言,定義它的文法的一種表示(如:加減乘除表達(dá)式和正則表達(dá)式等),然后再定義一個解釋器,該解釋器用來解釋我們的文法表示(表達(dá)式)。
解釋器模式的結(jié)構(gòu)與組合模式相似,不過其包含的組成元素比組合模式多,而且組合模式是對象結(jié)構(gòu)型模式,而解釋器模式是類行為型模式。
解釋器模式中包含四個角色:
抽象解釋器(Abstract Expression)角色:定義解釋器的接口,約定解釋器的解釋操作,主要包含解釋方法 interpret()。
終結(jié)符解釋器(Terminal Expression)角色:是抽象表達(dá)式的子類,用來實現(xiàn)文法中與終結(jié)符相關(guān)的操作,文法中的每一個終結(jié)符都有一個具體終結(jié)表達(dá)式與之相對應(yīng)。
非終結(jié)符解釋器(Nonterminal Expression)角色:也是抽象表達(dá)式的子類,用來實現(xiàn)文法中與非終結(jié)符相關(guān)的操作,文法中的每條規(guī)則都對應(yīng)于一個非終結(jié)符表達(dá)式。
環(huán)境(Context)角色:通常包含各個解釋器需要的數(shù)據(jù)或是公共的功能,一般用來傳遞被所有解釋器共享的數(shù)據(jù),后面的解釋器可以從這里獲取這些值。
解釋器模式類結(jié)構(gòu)圖如圖所示:
二、實現(xiàn)
接下來針對四個角色分別定義他們的實現(xiàn)。
抽象解釋器:
/** * 聲明一個抽象的解釋操作,這個接口為抽象語法樹中所有的節(jié)點所共享 * @author tcy * @Date 29-08-2022 */ public abstract class AbstractExpression { public abstract boolean interpret(String info); }
非終結(jié)符表達(dá)式:
/** * 非終結(jié)符表達(dá)式,為文法中的非終結(jié)符實現(xiàn)解釋操作。對文法中每一條規(guī)則R1、R2...Rn都需要一個具體的非終結(jié)符表達(dá)式類 * @author tcy * @Date 29-08-2022 */ public class NonTerminalExpression extends AbstractExpression{ private AbstractExpression address=null; private AbstractExpression name=null; private AbstractExpression id=null; public NonTerminalExpression(AbstractExpression address, AbstractExpression name, AbstractExpression id) { this.address = address; this.name = name; this.id = id; } @Override public boolean interpret(String info) { String s[]=info.split("-"); return address.interpret(s[0])&&name.interpret(s[1])&&id.interpret(s[2]); } }
終結(jié)符表達(dá)式:
** * 實現(xiàn)與文法中的終結(jié)符相關(guān)聯(lián)的解釋操作,文法中每一個終結(jié)符都有一個具體終結(jié)表達(dá)式與之相對應(yīng) * @author tcy * @Date 29-08-2022 */ public class TerminalExpression extends AbstractExpression{ private Set<String> set =new HashSet<String>(); public TerminalExpression(String[] data) { for(int i=0; i<data.length;i++) set.add(data[i]); } @Override public boolean interpret(String info) { if(set.contains(info)) { return true; } return false; } }
上下文環(huán)境:
/** * 上下文環(huán)境 * @author tcy * @Date 29-08-2022 */ public class Context { private String[] shuzis={"1","2","3","4","5","6","7","8","9","0"}; private String[] xiaoxiezimus={"a","b","c","d","e","f","g","h","i","j","k","l"}; private String[] daxiezimus={"A","B","C","D","E","F","G"}; private AbstractExpression infomation; public Context() { AbstractExpression shuzi=new TerminalExpression(shuzis); AbstractExpression xiaoxiezimu=new TerminalExpression(xiaoxiezimus); AbstractExpression daxiezimu=new TerminalExpression(daxiezimus); infomation=new NonTerminalExpression(shuzi,xiaoxiezimu,daxiezimu); } public void jieshi(String info) { boolean ok=infomation.interpret(info); if(ok) System.out.println("正確! ["+info+"] 滿足 [單個數(shù)字-單個小寫-單個大寫] 的條件"); else System.out.println("錯誤! ["+info+"] 不滿足 [單個數(shù)字-單個小寫-單個大寫] 的條件"); } }
客戶端:
/** * @author tcy * @Date 29-08-2022 */ public class Client { public static void main(String[] args) { Context people=new Context(); people.jieshi("2-a-A"); people.jieshi("11-A-5"); people.jieshi("你-好-吖"); people.jieshi("2aA"); } }
以上為解釋器模式的簡單案例,讀者可以拉取代碼到本地進(jìn)行學(xué)習(xí),本地源碼下載。
三、應(yīng)用場景
解釋器模式在實際的軟件開發(fā)中使用比較少,因為它會引起效率、性能以及維護(hù)等問題。
在JDK中的正則表達(dá)式中的Pattern類和Spring里面的ExpressionParse接口使用的是解釋器模式的思想。
當(dāng)一個語言需要解釋執(zhí)行,并且語言中的句子可以表示為一個抽象語法樹的時候,如 XML 文檔解釋,整體來說還是一種應(yīng)用較少的設(shè)計模式。
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
從零開始讓你的Spring?Boot項目跑在Linux服務(wù)器
這篇文章主要給大家介紹了如何從零開始讓你的Spring?Boot項目跑在Linux服務(wù)器的相關(guān)資料,由于springboot是內(nèi)嵌了tomcat,所以可以直接將項目打包上傳至服務(wù)器上,需要的朋友可以參考下2021-11-11Java中將String類型依照某個字符分割成數(shù)組的方法
下面小編就為大家分享一篇Java中將String類型依照某個字符分割成數(shù)組的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03IntelliJ IDEA 的 Spring 項目如何查看 @Value 的配置和值(方法詳解)
這篇文章主要介紹了IntelliJ IDEA 的 Spring 項目如何查看 @Value 的配置和值,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫詳解
這篇文章主要為大家詳細(xì)介紹了Java執(zhí)行SQL腳本文件到數(shù)據(jù)庫的相關(guān)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06深入了解SpringBoot中@InitBinder注解的使用
這篇文章主要介紹了深入了解SpringBoot中@InitBinder注解的使用,@InitBinder注解可以作用在被@Controller注解的類的方法上,表示為當(dāng)前控制器注冊一個屬性編輯器,用于對WebDataBinder進(jìn)行初始化,且只對當(dāng)前的Controller有效,需要的朋友可以參考下2023-10-10