23種設計模式(14):解釋器模式

定義:給定一種語言,定義他的文法的一種表示,並定義一個解釋器,該解釋器使用該表示來解釋語言中句子。 sql

類型:行爲類模式 express

類圖: 設計模式

23種設計模式(14):解釋器模式 - 第1張  | 快課網

解釋器模式是一個比較少用的模式,本人以前也沒有用過這個模式。下面咱們就來一塊兒看一下解釋器模式。 工具

 

解釋器模式的結構 性能

  • 抽象解釋器:聲明一個全部具體表達式都要實現的抽象接口(或者抽象類),接口中主要是一個interpret()方法,稱爲解釋操做。具體解釋任務由它的各個實現類來完成,具體的解釋器分別由終結符解釋器TerminalExpression和非終結符解釋器NonterminalExpression完成。
  • 終結符表達式:實現與文法中的元素相關聯的解釋操做,一般一個解釋器模式中只有一個終結符表達式,但有多個實例,對應不一樣的終結符。終結符一半是文法中的運算單元,好比有一個簡單的公式R=R1+R2,在裏面R1和R2就是終結符,對應的解析R1和R2的解釋器就是終結符表達式。
  • 非終結符表達式:文法中的每條規則對應於一個非終結符表達式,非終結符表達式通常是文法中的運算符或者其餘關鍵字,好比公式R=R1+R2中,+就是非終結符,解析+的解釋器就是一個非終結符表達式。非終結符表達式根據邏輯的複雜程度而增長,原則上每一個文法規則都對應一個非終結符表達式。
  • 環境角色:這個角色的任務通常是用來存放文法中各個終結符所對應的具體值,好比R=R1+R2,咱們給R1賦值100,給R2賦值200。這些信息須要存放到環境角色中,不少狀況下咱們使用Map來充當環境角色就足夠了。

代碼實現 spa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Context { }
abstract class Expression {
     public abstract Object interpreter ( Context ctx ) ;
}
class TerminalExpression extends Expression {
     public Object interpreter ( Context ctx ) {
         return null ;
     }
}
class NonterminalExpression extends Expression {
     public NonterminalExpression ( Expression . . . expressions ) {
 
     }
     public Object interpreter ( Context ctx ) {
         return null ;
     }
}
public class Client {
     public static void main ( String [ ] args ) {
         String expression = "" ;
         char [ ] charArray = expression . toCharArray ( ) ;
         Context ctx = new Context ( ) ;
         Stack <Expression> stack = new Stack <Expression> ( ) ;
         for ( int i = 0 ; i < charArray . length ; i ++ ) {
             //進行語法判斷,遞歸調用
         }
         Expression exp = stack . pop ( ) ;
         exp . interpreter ( ctx ) ;
     }
}

 

文法遞歸的代碼部分須要根據具體的狀況來實現,所以在代碼中沒有體現。抽象表達式是生成語法集合的關鍵,每一個非終結符表達式解釋一個最小的語法單元,而後經過遞歸的方式將這些語法單元組合成完整的文法,這就是解釋器模式。 設計

 

解釋器模式的優缺點 對象

解釋器是一個簡單的語法分析工具,它最顯著的優勢就是擴展性,修改語法規則只須要修改相應的非終結符就能夠了,若擴展語法,只須要增長非終結符類就能夠了。 遞歸

可是,解釋器模式會引發類的膨脹,每一個語法都須要產生一個非終結符表達式,語法規則比較複雜時,就可能產生大量的類文件,爲維護帶來很是多的麻煩。同時,因爲採用遞歸調用方法,每一個非終結符表達式只關心與本身相關的表達式,每一個表達式須要知道最終的結果,必須經過遞歸方式,不管是面向對象的語言仍是面向過程的語言,遞歸都是一個不推薦的方式。因爲使用了大量的循環和遞歸,效率是一個不容忽視的問題。特別是用於解釋一個解析複雜、冗長的語法時,效率是難以忍受的。 接口

 

解釋器模式的適用場景

在如下狀況下可使用解釋器模式:

  • 有一個簡單的語法規則,好比一個sql語句,若是咱們須要根據sql語句進行rm轉換,就可使用解釋器模式來對語句進行解釋。
  • 一些重複發生的問題,好比加減乘除四則運算,可是公式每次都不一樣,有時是a+b-c*d,有時是a*b+c-d,等等等等個,公式變幻無窮,可是都是由加減乘除四個非終結符來鏈接的,這時咱們就可使用解釋器模式。

注意事項

解釋器模式真的是一個比較少用的模式,由於對它的維護實在是太麻煩了,想象一下,一坨一坨的非終結符解釋器,假如不是事先對文法的規則瞭如指掌,或者是文法特別簡單,則很難讀懂它的邏輯。解釋器模式在實際的系統開發中使用的不多,由於他會引發效率、性能以及維護等問題。

相關文章
相關標籤/搜索