【Shell指令碼】Shell總結
阿新 • • 發佈:2020-11-22
直譯器模式
直譯器模式Interpreter Pattern
提供了評估語言的語法或表示式的方式,它屬於行為型模式,這種模式實現了一個表示式介面,該介面解釋一個特定的上下文,直譯器模式通常被用在SQL
解析、符號處理引擎等。
描述
在軟體開發中,會遇到有些問題多次重複出現,而且有一定的相似性和規律性,如果將它們歸納成一種簡單的語言,那麼這些問題例項將是該語言的一些句子,這樣就可以用編譯原理中的直譯器模式來實現了。直譯器模式是給分析物件定義一個語言,並定義該語言的文法表示,再設計一個解析器來解釋語言中的句子,也就是說,用編譯語言的方式來分析應用中的例項。這裡提到的文法和句子的概念同編譯原理中的描述相同,文法指語言的語法規則,而句子是語言集中的元素。
模式角色
- 抽象表示式
Expression
角色: 宣告一個所有的具體表達式角色都需要實現的抽象介面,這個介面主要是一個interpret()
方法,稱做解釋操作。 - 終結符表示式
Terminal Expression
角色: 實現了抽象表示式角色所要求的介面,主要是一個interpret()
方法,文法中的每一個終結符都有一個具體終結表示式與之相對應,比如有一個簡單的公式R=R1+R2
,在裡面R1
和R2
就是終結符,對應的解析R1
和R2
的直譯器就是終結符表示式。 - 非終結符表示式
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