Java设计模式之行为型:解释器模式
一、什么是解釋器模式:
????????解釋器模式,就是定義語言的文法,并建立一個解釋器來解釋該語言中的句子,通過構建解釋器,解決某一頻繁發生的特定類型問題實例。
這里我們將語言理解成使用規定格式和語法的代碼
????????解釋器模式描述了如何構成一個簡單的語言解釋器,主要應用在使用面向對象語言開發的編譯器中,它描述了如何為簡單的語言定義一個文法,如何在該語言中表示一個句子,以及如何解釋這些句子。?????
? ? ? ? 例如我們經常利用正則表達式檢測某些字符串是否符合我們規定的格式。這里正則表達式就是解釋器模式的應用,解釋器為正則表達式定義了一個文法,如何表示一個特定的正則表達式,以及如何解釋這個正則表達式。
????????解釋器模式中除了能夠使用文法規則來定義一個語言,還能通過使用抽象語法樹來更加直觀表示、更好地地表示一個語言的構成,每一顆抽象語法樹對應一個語言實例。抽象語法樹描述了如何構成一個復雜的句子,通過對抽象語法樹的分析,可以識別出語言中的終結符和非終結符類。 在解釋器模式中由于每一種終結符表達式、非終結符表達式都會有一個具體的實例與之相對應,所以系統的擴展性比較好。
二、UML結構圖:
- AbstractExpression:抽象解釋器,聲明一個抽象的解釋操作方法 interpret()。具體解釋任務由它的各個實現類來完成,具體解釋器分別由終結符解釋器 TerminalExpression 和非終結符解釋器 NonterminalExpression 完成。
- TerminalExpression:終結符表達式,實現與文法中的元素相關聯的解釋操作,通常一個解釋器模式中只有一個終結符表達式,但有多個實例,對應不同的終結符。終結符一般是文法中的運算單元,比如有一個簡單的公式 R = R1 + R2,在里面 R1 和R2 就是終結符,解析 R1 和 R2 的解釋器就是終結符表達式。
- NonterminalExpression:非終結符表達式,文法中的每條規則對應于一個非終結符表達式,非終結符表達式一般是文法中的運算符或者其他關鍵字,比如公式 R = R1 + R2中,+就是非終結符,解析+的解釋器就是一個非終結符表達式。非終結符表達式根據邏輯的復雜程度而增加,原則上每個文法規則都對應一個非終結符表達式。
- Context:環境類,包含解釋器之外的一些全局信息,這個角色的任務一般是用來存放文法中各個終結符所對應的具體值,比如 R = R1 + R2,我們給 R1 賦值 100,給 R2 賦值 200。這些信息需要存放到環境角色中,很多情況下我們使用Map來充當環境角色就足夠了。
- Client:客戶類
三、代碼實現:
?現在我們用解釋器模式來實現一個基本的加、減、乘、除和求模運算。例如用戶輸入表達式“3 * 4 / 2 % 4”,輸出結果為2。下圖為該實例的UML結構圖:
抽象語法樹:
抽象表達式:Node.java。
public interface Node{public int interpret(); }?非終結表達式:ValueNode.java。主要用解釋該表達式的值。
public class ValueNode implements Node{private int value;public ValueNode(int value){this.value=value;}public int interpret(){return this.value;} }?終結表達式抽象類,由于該終結表達式需要解釋多個運算符號,同時用來構建抽象語法樹:
public abstract class SymbolNode implements Node{protected Node left;protected Node right;public SymbolNode(Node left,Node right){this.left=left;this.right=right;} }MulNode.java:
public class MulNode extends SymbolNode{public MulNode(Node left,Node right){super(left,right);}public int interpret(){return left.interpret() * right.interpret();} }ModNode.java:
public class ModNode extends SymbolNode{public ModNode(Node left,Node right){super(left,right);}public int interpret(){return super.left.interpret() % super.right.interpret();} }DivNode.java:
public class DivNode extends SymbolNode{public DivNode(Node left,Node right){super(left,right);}public int interpret(){return super.left.interpret() / super.right.interpret();} }Calculator.java:
public class Calculator{private String statement;private Node node;public void build(String statement){Node left=null,right=null;Stack stack=new Stack();String[] statementArr=statement.split(" ");for(int i=0;i<statementArr.length;i++){ if(statementArr[i].equalsIgnoreCase("*")){left=(Node)stack.pop();int val=Integer.parseInt(statementArr[++i]);right=new ValueNode(val); stack.push(new MulNode(left,right));}else if(statementArr[i].equalsIgnoreCase("/")){left=(Node)stack.pop();int val=Integer.parseInt(statementArr[++i]);right=new ValueNode(val); stack.push(new DivNode(left,right)); }else if(statementArr[i].equalsIgnoreCase("%")){left=(Node)stack.pop();int val=Integer.parseInt(statementArr[++i]);right=new ValueNode(val); stack.push(new ModNode(left,right)); }else{stack.push(new ValueNode(Integer.parseInt(statementArr[i])));}}this.node=(Node)stack.pop();}public int compute()return node.interpret();} }客戶端:Client.java:
public class Client{public static void main(String args[]){String statement = "3 * 2 * 4 / 6 % 5";Calculator calculator = new Calculator();calculator.build(statement);int result = calculator.compute();System.out.println(statement + " = " + result); } }運行結果:3 * 2 * 4 / 6 % 5 = 4
四、解釋器模式小結:
1、優點:
(1)解釋器是一個簡單的語法分析工具,它最顯著的優點就是擴展性,修改語法規則只需要修改相應的非終結符就可以了,若擴展語法,只需要增加非終結符類就可以了。
(2)增加了新的解釋表達式的方式。
(3)易于實現文法。
2、缺點:
(1)解釋器模式會引起類的膨脹,每個語法都需要產生一個非終結符表達式,語法規則比較復雜時,就可能產生大量的類文件,為維護帶來非常多的麻煩。
(2)效率低下,采用遞歸調用方法,每個非終結符表達式只關心與自己相關的表達式,每個表達式需要知道最終的結果,必須通過遞歸方式,無論是面向對象的語言還是面向過程的語言,遞歸都是一個不推薦的方式。由于使用了大量的循環和遞歸,效率是一個不容忽視的問題。特別是用于解釋一個解析復雜、冗長的語法時,效率是難以忍受的。
3、適用場景:
(1)有一個簡單的語法規則,比如一個sql語句,如果我們需要根據sql語句進行rm轉換,就可以使用解釋器模式來對語句進行解釋。
(2)一些重復發生的問題,比如加減乘除四則運算,但是公式每次都不同,有時是a+b-c*d,有時是a*b+c-d,等等,公式千變萬化,但是都是由加減乘除四個非終結符來連接的,這時我們就可以使用解釋器模式。
?設計模式系列文章:
Java設計模式之創建型:工廠模式詳解(簡單工廠+工廠方法+抽象工廠)
Java設計模式之創建型:建造者模式
Java設計模式之創建型:單例模式
Java設計模式之創建型:原型模式
Java設計模式之結構型:適配器模式
Java設計模式之結構型:裝飾器模式
Java設計模式之結構型:代理模式
Java設計模式之結構型:橋接模式
Java設計模式之結構型:外觀模式
Java設計模式之結構型:組合模式
Java設計模式之結構型:享元模式
Java設計模式之行為型:策略模式
Java設計模式之行為型:模板方法模式
Java設計模式之行為型:責任鏈模式
Java設計模式之行為型:觀察者模式
Java設計模式之行為型:訪問者模式
Java設計模式之行為型:中介者模式
Java設計模式之行為型:命令模式
Java設計模式之行為型:狀態模式
Java設計模式之行為型:備忘錄模式
Java設計模式之行為型:迭代器模式
Java設計模式之行為型:解釋器模式
原博客鏈接:
設計模式讀書筆記-----解釋器模式_chenssy 的技術博客-CSDN博客
23種設計模式(14):解釋器模式_三級小野怪的專欄-CSDN博客_解釋器模式
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Java设计模式之行为型:解释器模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式之行为型:访问者模式
- 下一篇: Java虚拟机:性能监控与故障处理工具