淺談Java解釋器模式
**請(qǐng)注意!請(qǐng)注意!!!**今天講給大家講解非常“有用”的設(shè)計(jì)模式,解釋器模式!??!
設(shè)計(jì)模式有三大種類,一種是創(chuàng)建型模式,一種是結(jié)構(gòu)型模式,最后一種是行為性模式,那么解釋器模式屬于哪一種呢?帶領(lǐng)大家一起來(lái)了解學(xué)習(xí)解釋器模式!
本次介紹圍繞著以下五點(diǎn)展開(kāi)。什么是解釋器模式?用來(lái)做什么?怎么做?有哪些優(yōu)點(diǎn)?有哪些不足?
解釋器模式顧名思義,就是用來(lái)定義和解釋。
給定一種特定語(yǔ)言,這個(gè)語(yǔ)言有特定的文法,解釋器可以解釋這個(gè)語(yǔ)言中的句子含義。即解釋器提供一種語(yǔ)言,如java,同時(shí)它也提供一種手段去解析java語(yǔ)言寫出來(lái)的代碼。
大家可能也會(huì)想到這就是類似編譯原理,一個(gè)算術(shù)表達(dá)式要經(jīng)過(guò)詞法分析,語(yǔ)法分析,構(gòu)建語(yǔ)法樹(shù)啥的;還有正則表達(dá)式;SQL解析,編譯器等等,其實(shí)都是解析式模式的一種實(shí)現(xiàn)。
那怎么做?一個(gè)是說(shuō)要有像編譯原理中的終結(jié)符和非終結(jié)符,構(gòu)建一顆語(yǔ)法樹(shù)。同時(shí)需要有一個(gè)環(huán)境類,來(lái)管理輸入和輸出。
這里我們舉一個(gè)例子,輸入一個(gè)表達(dá)式a+b-c+d-e,同時(shí)給這5個(gè)變量賦值,計(jì)算出它的值。那么使用解釋器模式要如何實(shí)現(xiàn)?
我們?yōu)榻忉屍鞫x一個(gè)抽象解釋類Expression,所有的流轉(zhuǎn)通過(guò)interpreter方法實(shí)現(xiàn)。
上下文管理輸入輸出使用一個(gè)HashMap
去實(shí)現(xiàn)。
定義符號(hào)解釋類SymbolExpression
,加法解釋類AddExpreesion
,減法解釋類SubExpression
。
類圖:
具體代碼實(shí)現(xiàn):
public abstract class Expression { // map中攜帶了表達(dá)式中的變量名(key) 和 對(duì)應(yīng)的值(value) public abstract int interpreter(Map<String, Integer> var); } public class VarExpression extends Expression { // 表達(dá)式中對(duì)應(yīng)的變量名 String key; public VarExpression(String var) { this.key = var; } @Override public int interpreter(Map<String, Integer> var) { return var.get(key); } } public class SymbolExpression extends Expression { // +或-符號(hào) 左右兩邊的表達(dá)式 Expression var1; Expression var2; public SymbolExpression(Expression var1, Expression var2) { this.var1 = var1; this.var2 = var2; } @Override public int interpreter(Map<String, Integer> var) { // 實(shí)現(xiàn)抽象方法 // 該類不需要用到該方法 默認(rèn)返回0 return 0; } } public class AddExpression extends SymbolExpression { public AddExpression(Expression var1, Expression var2) { super(var1, var2); } @Override public int interpreter(Map<String, Integer> var) { return var1.interpreter(var) + var2.interpreter(var); } } public class SubExpression extends SymbolExpression { public SubExpression(Expression var1, Expression var2) { super(var1, var2); } @Override public int interpreter(Map<String, Integer> var) { return var1.interpreter(var) - var2.interpreter(var); } } public class Calculator { // 表達(dá)式 private Expression expression; // 解析出表達(dá)式 public Calculator(String expStr) { Stack<Expression> stack = new Stack<>(); Expression left, right = null; char[] expStrCharArray = expStr.toCharArray(); for(int i = 0; i < expStrCharArray.length; i++) { switch (expStrCharArray[i]) { case '+':// 加法運(yùn)算 獲取左邊表達(dá)式 右邊數(shù)值 left = stack.pop(); right = new VarExpression(String.valueOf(expStrCharArray[++i])); stack.push(new AddExpression(left, right)); break; case '-':// 減法運(yùn)算 獲取左邊表達(dá)式 右邊數(shù)值 left = stack.pop(); right = new VarExpression(String.valueOf(expStrCharArray[++i])); stack.push(new SubExpression(left, right)); break; default:// 表達(dá)式中的變量 stack.push(new VarExpression(String.valueOf(expStrCharArray[i]))); break; } } // 最后會(huì)獲得被Expression包裝起來(lái)的一個(gè)表達(dá)式 this.expression = stack.pop(); } // 計(jì)算結(jié)果 public int run(Map<String, Integer> var) { return this.expression.interpreter(var); } } public class Client { public static void main(String[] args) throws IOException { String expStr = getExpStr(); Map<String, Integer> var = getValue(expStr); Calculator calculator = new Calculator(expStr); System.out.println("運(yùn)算結(jié)果:" + expStr + "=" + calculator.run(var)); } //獲得表達(dá)式 public static String getExpStr() { return "a+b-c+d-e"; } //獲得值映射 public static HashMap<String, Integer> getValue(String expStr) throws IOException { HashMap<String, Integer> map = new HashMap<>(); for(char ch : expStr.toCharArray()) { if(ch != '+' && ch != '-' ) { if(! map.containsKey(String.valueOf(ch))) { System.out.print("請(qǐng)輸入" + String.valueOf(ch) + "的值:"); String in = (new BufferedReader(new InputStreamReader(System.in))).readLine(); map.put(String.valueOf(ch), Integer.valueOf(in)); } } } return map; } }
結(jié)果
/*
請(qǐng)輸入a的值:1
請(qǐng)輸入b的值:3
請(qǐng)輸入c的值:5
請(qǐng)輸入d的值:7
請(qǐng)輸入e的值:9
運(yùn)算結(jié)果:a+b-c+d-e=-3
*/
或許看代碼會(huì)有點(diǎn)云里霧里,希望大家能手動(dòng)敲一遍,或許會(huì)對(duì)整個(gè)過(guò)程有更進(jìn)一步的理解,在編碼的同時(shí)不斷思考,提升自我。
很容易發(fā)現(xiàn)解釋器模式是屬于行為性模式的一種,這種模式更關(guān)注對(duì)象之間的通信。
解釋器模式優(yōu)點(diǎn),結(jié)構(gòu)清晰,可拓展性好。但也有缺點(diǎn),一般用在比較底層場(chǎng)景,平常敲代碼可使用的場(chǎng)景比較少,并且解釋器模式采用的是遞歸的方式,當(dāng)語(yǔ)言比較長(zhǎng),性能不高;同時(shí)如果文法比較復(fù)雜,也需要更多的相應(yīng)解釋類。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- Java設(shè)計(jì)模式之解釋器模式
- 深入理解Java設(shè)計(jì)模式之解釋器模式
- Java設(shè)計(jì)模式之java解釋器模式詳解
- Java基于解釋器模式實(shí)現(xiàn)定義一種簡(jiǎn)單的語(yǔ)言功能示例
- Java設(shè)計(jì)模式之解釋器模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java設(shè)計(jì)模式編程之解釋器模式的簡(jiǎn)單講解
- 解析Java的設(shè)計(jì)模式編程之解釋器模式的運(yùn)用
- JAVA設(shè)計(jì)模式之解釋器模式詳解
- Java實(shí)現(xiàn)自定義語(yǔ)言和表達(dá)式解析的解釋器模式
相關(guān)文章
java實(shí)現(xiàn)清理DNS Cache的方法
這篇文章主要介紹了java實(shí)現(xiàn)清理DNS Cache的方法,分析了幾種常用的清理方法,并給出了反射清理的完整實(shí)例,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01Java?Map.values()方法之如何獲取Map集合中的所有鍵值對(duì)象
這篇文章主要介紹了Java?Map.values()方法之如何獲取Map集合中的所有鍵值對(duì)象問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Spring定時(shí)任務(wù)輪詢本地?cái)?shù)據(jù)庫(kù)實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Spring定時(shí)任務(wù)輪詢本地?cái)?shù)據(jù)庫(kù)實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01詳解SpringBoot下文件上傳與下載的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot下文件上傳與下載的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法
本篇文章主要介紹了spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Java中增強(qiáng)for循環(huán)的實(shí)現(xiàn)原理和坑詳解
增強(qiáng)的for循環(huán)是在傳統(tǒng)的for循環(huán)中增加的強(qiáng)大的迭代功能的循環(huán),是在jdk1.5之后提出來(lái)的。下面這篇文章主要給大家介紹了關(guān)于Java中增強(qiáng)for循環(huán)的實(shí)現(xiàn)原理和坑的相關(guān)資料,需要的朋友可以參考下2018-04-04SpringMVC中處理靜態(tài)資源的過(guò)程詳解
本文給大家介紹SpringMVC中處理靜態(tài)資源的過(guò)程,結(jié)合示例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11