當前位置:才華齋>計算機>java語言>

解析Java的設計模式程式設計之直譯器模式的運用

java語言 閱讀(2.19W)

0.直譯器(Interpreter)模式定義 :

解析Java的設計模式程式設計之直譯器模式的運用

給定一門語言,定義它的文法的一種表示,並定義一個直譯器,該直譯器使用該表示來解釋語言中句子。 屬於行為型模式。

直譯器模式在實際的系統開發中使用的非常少,因為它會引起效率、效能以及維護等問題。

直譯器模式的通用類圖如圖所示。

1.直譯器模式的優點

直譯器是一個簡單語法分析工具,它最顯著的優點就是擴充套件性,修改語法規則只要修改相應的非終結符表示式就可以了,若擴充套件語法,則只要增加非終結符類就可以了。

2.直譯器模式的缺點

直譯器模式會引起類膨脹:每個語法都要產生一個非終結符表示式,語法規則比較複雜時,就可能產生大量的類檔案,為維護帶來了非常多的麻煩。

直譯器模式採用遞迴呼叫方法:每個非終結符表示式只關心與自己有關的表示式,每個表示式需要知道最終的結果,必須一層一層地剝繭,無論是面向過程的語言還是面向物件的語言,遞迴都是在必要條件下使用的',它導致除錯非常複雜。想想看,如果要排查一個語法錯誤,我們是不是要一個一個斷點的除錯下去,直到最小的語法單元。

效率問題:直譯器模式由於使用了大量的迴圈和遞迴,效率是個不容忽視的問題,特別是用於解析複雜、冗長的語法時,效率是難以忍受的。

3.直譯器模式的使用場景

重複發生的問題可以使用直譯器模式:例如,多個應用伺服器,每天產生大量的日誌,需要對日誌檔案進行分析處理,由於各個伺服器的日誌格式不同,但是資料要素是相同的,按照直譯器的說法就是終結符表示式都是相同的,但是非終結符表示式就需要制定了。在這種情況下,可以通過程式來一勞永逸地解決該問題。

一個簡單語法需要解釋的場景:為什麼是簡單?看看非終結表示式,文法規則越多,複雜度越高,而且類間還要進行遞迴呼叫(看看我們例子中的堆疊),不是一般地複雜。想想看,多個類之間的呼叫你需要什麼樣的耐心和信心去排查問題。因此,直譯器模式一般用來解析比較標準的字符集,例如SQL語法分析,不過該部分逐漸被專用工具所取代。在某些特用的商業環境下也會採用直譯器模式,我們剛剛的例子就是一個商業環境,而且現在模型運算的例子非常多,目前很多商業機構已經能夠提供出大量的資料進行分析。

4.簡單例子

/** * 宣告一個抽象的解釋操作 */ public interface Interpreter { public void interpret(Context context); //實際中,可以有個返回的型別,定義解釋出的資料物件 } public class XmlSaxInterpreter implements Interpreter { @Override public void interpret(Context context) { tln("xml sax Interpreter:" + ata()); } } public class XmlDomInterpreter implements Interpreter { @Override public void interpret(Context context) { tln("xml dom Interpreter:" + ata()); } } /** * 包含直譯器之外的一些資訊 */ public class Context { private String data; public String getData() { return data; } public void setData(String data) { = data; } } public class Test { public static void main(String[] args) { Context context = new Context(); ata("一段xml資料"); new XmlSaxInterpreter()rpret(context); new XmlDomInterpreter()rpret(context); } }

5.直譯器模式的注意事項

儘量不要在重要的模組中使用直譯器模式,否則維護會是一個很大的問題。在專案中可以使用shell、JRuby、Groovy等指令碼語言來代替直譯器模式,彌補Java編譯型語言的不足。我們在一個銀行的分析型專案中就採用JRuby進行運算處理,避免使用直譯器模式的四則運算,效率和效能各方面表現良好。