第二十三章 Caché 設計模式 解釋器模式
定義
給定一個語義,語義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
使用場景
-
如果一種特性類型的問題發生的頻率足夠高,那麼可能就值得將該問題的各個實例表述爲一個簡單語言中的句子。這樣就可以構建一個解釋器,解釋器通過解釋這些句子來解決該問題。
-
有一個簡單的語法規則,比如編碼轉換.翻譯。
-
正則表達式,瀏覽器。
優點
擴展性強,若要新增乘,除,添加相應的非終結表達式,修改計算邏輯即可。
缺點
- 需要建大量的類,因爲每一種語法都要建一個非終結符的類。
- 解釋的時候採用遞歸調用方法,導致有時候函數的深度會很深,影響效率。
結構圖
描述
用abc來代替123數字。
完整示例
抽象解釋器
Class PHA.YX.Design.Interpreter.Expression Extends %RegisteredObject
{
Method Interpreter(context As Context) As %Integer [ Abstract ]
{
q 0
}
}
上下文
Class PHA.YX.Design.Interpreter.Context Extends %RegisteredObject
{
Property map As %ArrayOfDataTypes;
Method Add(s As Expression, value As %Integer)
{
d ..map.SetAt(value, s)
}
Method Lookup(s As Expression)
{
q ..map.GetAt(s)
}
}
終結符表達式
Class PHA.YX.Design.Interpreter.TerminalExpression Extends Expression
{
Property variable As %String;
Method %OnNew(variable As %String) As %Status [ Private, ServerOnly = 1 ]
{
s ..variable = variable
Quit $$$OK
}
Method Interpreter(context As Context) As %Integer
{
q context.Lookup($this)
}
}
非終結符表達式
Class PHA.YX.Design.Interpreter.NonTerminalExpression Extends Expression
{
Property e1 As Expression;
Property e2 As Expression;
Method %OnNew(e1 As Expression, e2 As Expression) As %Status [ Private, ServerOnly = 1 ]
{
s ..e1 = e1
s ..e2 = e2
Quit $$$OK
}
}
Class PHA.YX.Design.Interpreter.MinusOperation Extends NonTerminalExpression
{
Method %OnNew(e1 As Expression, e2 As Expression) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(e1, e2)
Quit $$$OK
}
Method Interpreter(context As Context) As %Integer
{
q ..e1.Interpreter(context) - ..e2.Interpreter(context)
}
}
Class PHA.YX.Design.Interpreter.PlusOperation Extends NonTerminalExpression
{
Method %OnNew(e1 As Expression, e2 As Expression) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(e1, e2)
Quit $$$OK
}
Method Interpreter(context As Context) As %Integer
{
q ..e1.Interpreter(context) + ..e2.Interpreter(context)
}
}
調用
/// d ##class(PHA.YX.Design.Program).Interpreter()
ClassMethod Interpreter()
{
s context = ##class(PHA.YX.Design.Interpreter.Context).%New()
s a = ##class(PHA.YX.Design.Interpreter.TerminalExpression).%New("a")
s b = ##class(PHA.YX.Design.Interpreter.TerminalExpression).%New("b")
s c = ##class(PHA.YX.Design.Interpreter.TerminalExpression).%New("c")
d context.Add(a, 4)
d context.Add(b, 8)
d context.Add(c, 6)
s min= ##class(PHA.YX.Design.Interpreter.MinusOperation).%New(a,b).Interpreter(context)
w min,!
w ##class(PHA.YX.Design.Interpreter.MinusOperation).%New(##class(PHA.YX.Design.Interpreter.PlusOperation).%New(a, b), c).Interpreter(context),!
}
DHC-APP> d ##class(PHA.YX.Design.Program).Interpreter()
-4
6
思考
把數字解釋解釋成對應英文。