設計模式之直譯器模式
前言
直譯器模式和介面卡模式有些異曲同工之妙。介面卡是用介面使之相容,直譯器是用語言來解釋句子。
直譯器模式
給定義一個語言,定義它的文法(法規)的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。
也就是說將一句話,轉變成實際的命令程式執行。
情景
我們都熟悉的程式語言。人們要控制計算機一定要通過計算機語言向計算機發出命令,否則計算機時不會懂得人們的指令的。這裡的程式語言就相當於時直譯器。
優缺點
優點:
- 很容易的改變和擴充套件文法,因為該模式使用類來表示文法規則,你可使用繼承來改變或擴充套件該文法。
- 容易實現文法,因為定義抽象語法樹中各個節點的類的實現大體類似
缺點:
- 為文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以管理和維護。
- 當文法非常複雜時,建議使用其他的技術如語法分析程式或編譯器來處理。
應用
正規表示式,瀏覽器。只要是可以用語言來描述的,都可以。
它需要解決的是:如果一種特定型別的問題發生的頻率足夠高,那麼可能就值得將該問題的各個例項表述為一個簡單語言中的句子。這樣就可以構建一個直譯器,該直譯器通過解釋這些句子來解決該問題。
程式碼展示
音樂直譯器程式:
演奏內容類:
//演奏內容
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
{
string playKey = context.PlayText.Substring(0, 1);//將當前的演奏文字第一條命令獲得命令字母和其引數值
context .PlayText = context .PlayText .Substring (2);
double playValue = Convert .ToDouble (context .PlayText .Substring (0,context .PlayText .IndexOf (" ")));
//獲得playkey和 playvalue後將其從演奏文字中移除
context.PlayText = context.PlayText.Substring(context.PlayText.IndexOf(" ") + 1);
Excute(playKey, playValue);
}
}
//執行----------抽象方法執行,不同的文法子類有不同的執行處理
public abstract void Excute(string key, double value);
}
音符類:(終結符表示式—-實現解釋操作terminal)
//音符類
class Note:Expression
{
public override void Excute(string key, double value)
{
string note = "";
switch (key)
{
//如果獲得的key是C,則演奏1(do)
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.WriteLine("{0}",note );
}
}
//音階類
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.WriteLine("{0}",scale );
}
}
//這裡還可以新增速度類等
客戶端程式碼:
class Program
{
static void Main(string[] args)
{
PlayContext context = new PlayContext();
//音樂--上海灘
Console.WriteLine("上海灘");
//播放的音符,音階,及旋律拍子-----O 2指中音區的音符 ;E代表了3這個音;0.5指半拍。
context.PlayText = "O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ";
Expression expression = null;
try
{
while (context.PlayText.Length > 0)
{
string str = context.PlayText.Substring(0, 1);
switch (str)
{
case "O": //首欄位為O時,表示式例項化為音階
expression = new Scale();
break;
case "C": //首字母為CDEFGAB時,例項化音符
case "D":
case "E":
case "F":
case "G":
case "A":
case "B":
case "P": //休止符
expression = new Note();
break;
}
expression.Interpret(context);
}
}
catch (Exception ex)
{
Console.Write(ex.Message );
}
Console.ReadLine();
}
}
圖片解釋:
O 2指中音區的音符 ;E代表了3這個音;0.5指半拍,3指三拍
context.PlayText = “O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 “;
錯誤解決
解決:
將3後面加上一個空格
後記
今天又體驗了一把學習音樂的好處啊~
相關文章
- 23種設計模式之直譯器模式設計模式
- 折騰Java設計模式之直譯器模式Java設計模式
- 20.java設計模式之直譯器模式Java設計模式
- 軟體設計模式系列之十七——直譯器模式設計模式
- 簡說設計模式——直譯器模式設計模式
- 極簡設計模式-直譯器模式設計模式
- 設計模式--直譯器模式和狀態模式設計模式
- 設計模式(十五)直譯器設計模式
- Rust語言之GoF設計模式: 直譯器Interpreter模式RustGo設計模式
- 直譯器設計模式知識概括設計模式
- PHP設計模式(二十二)—直譯器模式(Interpreter PattPHP設計模式
- 設計模式 第十章 備忘錄模式、直譯器模式、狀態模式設計模式
- 直譯器模式(Interpreter)模式
- Java設計模式-17、直譯器模式-自定義語言的實現Java設計模式
- 設計模式之迭代器模式設計模式
- 24_直譯器模式模式
- 設計模式學習筆記(二十二)直譯器模式及其實現設計模式筆記
- 設計模式(二十一)——直譯器模式(Spring 框架中SpelExpressionParser原始碼分析)設計模式Spring框架Express原始碼
- golang設計模式之迭代器模式Golang設計模式
- Javascript設計模式之迭代器模式JavaScript設計模式
- 設計模式之-裝飾器模式設計模式
- 設計模式之【裝飾器模式】設計模式
- Go 設計模式之裝飾器模式Go設計模式
- C#設計模式之迭代器模式C#設計模式
- javascript設計模式 之 4 迭代器模式JavaScript設計模式
- java設計模式之裝飾器模式Java設計模式
- 23天設計模式之迭代器模式設計模式
- Java學設計模式之裝飾器模式Java設計模式
- 【趣味設計模式系列】之【裝飾器模式】設計模式
- 設計模式之裝飾器模式(decorator pattern)設計模式
- 16.java設計模式之迭代器模式Java設計模式
- PHP設計模式之裝飾器模式(Decorator)PHP設計模式
- 設計模式之策略模式設計模式
- 設計模式之代理模式設計模式
- 設計模式之Plugin模式設計模式Plugin
- 《設計模式》之代理模式設計模式
- 設計模式之命令模式設計模式
- 設計模式之-命令模式設計模式