1. 程式人生 > 實用技巧 >【Shell指令碼】Shell總結

【Shell指令碼】Shell總結

直譯器模式

直譯器模式Interpreter Pattern提供了評估語言的語法或表示式的方式,它屬於行為型模式,這種模式實現了一個表示式介面,該介面解釋一個特定的上下文,直譯器模式通常被用在SQL解析、符號處理引擎等。

描述

在軟體開發中,會遇到有些問題多次重複出現,而且有一定的相似性和規律性,如果將它們歸納成一種簡單的語言,那麼這些問題例項將是該語言的一些句子,這樣就可以用編譯原理中的直譯器模式來實現了。直譯器模式是給分析物件定義一個語言,並定義該語言的文法表示,再設計一個解析器來解釋語言中的句子,也就是說,用編譯語言的方式來分析應用中的例項。這裡提到的文法和句子的概念同編譯原理中的描述相同,文法指語言的語法規則,而句子是語言集中的元素。

模式角色

  • 抽象表示式Expression角色: 宣告一個所有的具體表達式角色都需要實現的抽象介面,這個介面主要是一個interpret()方法,稱做解釋操作。
  • 終結符表示式Terminal Expression角色: 實現了抽象表示式角色所要求的介面,主要是一個interpret()方法,文法中的每一個終結符都有一個具體終結表示式與之相對應,比如有一個簡單的公式R=R1+R2,在裡面R1R2就是終結符,對應的解析R1R2的直譯器就是終結符表示式。
  • 非終結符表示式Nonterminal Expression角色: 文法中的每一條規則都需要一個具體的非終結符表示式,非終結符表示式一般是文法中的運算子或者其他關鍵字,比如公式R=R1+R2
    中,+就是非終結符,解析+的直譯器就是一個非終結符表示式。
  • 環境Context角色: 這個角色的任務一般是用來存放文法中各個終結符所對應的具體值,比如R=R1+R2,我們給R1賦值100,給R2賦值200,這些資訊需要存放到環境角色中,很多情況下我們使用Map來充當環境角色就足夠了。

優點

  • 擴充套件性好,由於在直譯器模式中使用類來表示語言的文法規則,因此可以通過繼承等機制來改變或擴充套件文法。
  • 容易實現,在語法樹中的每個表示式節點類都是相似的,所以實現其文法較為容易。

缺點

  • 執行效率較低,直譯器模式中通常使用大量的迴圈和遞迴呼叫,當要解釋的句子較複雜時,其執行速度很慢,且程式碼的除錯過程也比較麻煩。
  • 會引起類膨脹,直譯器模式中的每條規則至少需要定義一個類,當包含的文法規則很多時,類的個數將急劇增加,導致系統難以管理與維護。
  • 可應用的場景比較少,在軟體開發中,需要定義語言文法的應用例項非常少,所以這種模式很少被使用到。

實現

function Context() {
    var sum = 0;
    var list = [];
    this.getSum = function() {
        return sum;
    }
    this.setSum = function(_sum) {
        sum = _sum;
    }
    this.add = function(eps) {
        list.push(eps);
    }
    this.getList = function() {
        return list;
    }
}

function PlusExpression() {
    this.interpret = function(context) {
        var sum = context.getSum();
        sum++;
        context.setSum(sum);
    }
}

function MinusExpression() {
    this.interpret = function(context) {
        var sum = context.getSum();
        sum--;
        context.setSum(sum);
    }
}

(function() {
    var context = new Context();
    context.setSum(20);
    //執行加法三次
    context.add(new PlusExpression());
    context.add(new PlusExpression());
    context.add(new PlusExpression());
    //執行減法兩次
    context.add(new MinusExpression());
    context.add(new MinusExpression());
    var list = context.getList();
    for (var i = 0; i < list.length; i++) {
        let expression = list[i];
        expression.interpret(context);
    }
    console.log(context.getSum()); // 21
})();

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

http://c.biancheng.net/view/1402.html
https://blog.csdn.net/itpinpai/article/details/51657199
https://www.runoob.com/design-pattern/interpreter-pattern.html