#解釋器模式(Interpreter Pattern)
##簡介
解釋器模式:給定一個語言,定義它的語法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
解釋器模式需要解決的是,如果一種特定類型的問題發生的頻率足夠高,那么可能就值得將該問題的各個實例表述為一個簡單語言中的句子。這樣就可以構建一個解釋器,該解釋器通過解釋這些句子來解決該問題。
比如說,我們常常會在字符串中搜索匹配字符或判斷一個字符串是否符合我們規定的格式,此時一般我們會用正則表達式匹配。解釋器為正則表達式定義了一個文法,如何表示一個特定的正則表達式,以及如何解釋這個正則表達式。
***當有一個語言需要解釋執行,并且你可以將該語言中的句子表示為一個抽象語法樹時,可以使用解釋器模式。***
用了解釋器模式,就意味著可以很容易地改變和擴展文法,因為該模式使用類來表示文法規則,你可以使用繼承來改變或者擴展該文法。也比較容易實現文法,因為定義抽象語法樹中各個節點的類的實現大體類似,這些類都易于直接編寫。
***解釋器模式也有不足的,解釋器模式為文法中的每一條規則至少定義了一個類,因此包含了許多規則的文法可能難以管理和維護。建議當文法非常復雜時,使用其它的技術如語法分析程序或編譯器生成器來處理。***
##實例
###音樂解釋器
演奏內容類(context)
```
//演奏內容
class PlayContext
{
//演奏文本
private string text;
public string PlayText
{
get {return text;}
set {text = value;}
}
}
```
表達式類(AbstractExpression)
```
abstract class Expression
{
//解釋器
public void Interpret(PlayContext context)
{
if (context.PlayText.Length == 0)
{
return;
}
else
{
//此方法用于將當前演奏文本第一條命令獲得命令字母和其參數值。例如"O 3 E 0.5 G 0.5 A 3"則playKey為O而playValue為3
string playKey = context.Playtext.subText.subString(0,1);
context.PlayText = context. PlayText.subString(2);
doublePlayValue = Convert.ToDouble(context.PlayText.SubString(0, context.PlayText.IndexOf("")));
context.PlayText = context.PlayText.substring(context.PlayText.IndexOf("") + 1);
Excute(playKey, playValue);
}
}
//執行
public abstract void Excute(string key, doubel value);
}
```
音符類(TerminalExpression)
```
class Note: Expression
{
public override void Excute(string key, double value)
{
string note ="";
switch (key)
{
case: "C":
note = "1";
break;
case: "D":
note = "2";
break;
case: "E":
note = "3";
break;
case: "F":
note = "4";
break;
case: "G":
note = "5";
break;
case: "A":
note = "6";
break;
case: "B":
note = "7";
break;
}
Console.Write("{0}", note);
}
}
```
音符類(TerminalExpression)
```
class Scale: Expression
{
public override void Excute(string key, double value)
{
string scale = "";
switch (Convert.ToInt32(value))
{
case 1:
scale = "低音";
break;
case 2:
scale = "中音";
break;
case 3:
scale = "高音";
break;
}
Console.Write("{0}",scale);
}
}
```
客戶端代碼
```
static void Main(string[] args)
{
PlayContext context = new PlayContext();
//音樂-上海灘
Console.WriteLine("上海灘:");
context.PlayText = "O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5";
Expression expression = null;
try
{
while (context.PlayText.Length > 0)
{
string str = context.PlayText.Substring(0.1);
switch (str)
{
case "O":
expression = new Scale();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "A":
case "B":
case "P":
expression = new Note();
break;
}
expression.Interpret(context);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
```
比如說 我現在要增加一個文法,就是演奏速度。
音速類
```
class Speed :Expression
{
public override void Excute(string key, double value)
{
string speed;
if (value < 500) {
speed = "快速";
} else if (value >= 1000)
{
speed = "慢速";
} else {
speed = "快速";
}
Console.Write("{0}",speed);
}
}
```
客戶端代碼(局部)
```
context.PlayText = "T 500 O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5";
Expression expression = null;
try
{
while (context.PlayText.Length > 0)
{
string str = context.PlayText.Substring(0.1);
switch (str)
{
case "O":
expression = new Scale();
break;
case "T":
expression = new Speed();
break;
case "C":
case "D":
case "E":
case "F":
case "G":
case "A":
case "A":
case "B":
case "P":
expression = new Note();
break;
}
expression.Interpret(context);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
```