通俗易懂設計模式解析——直譯器模式
前言
今天我們來講直譯器模式【Interpreter Pattern】,如何理解這一個模式呢?一個簡單的例子、中英文翻譯器這個東西的作用是啥呢?將不知道的英文翻譯成中文以便於理解、或者把中文翻譯成英文來使用。其中目的也就是將語言進行翻譯解釋方便去理解使用。那麼直譯器模式呢?也有相似的邏輯、該模式實現了一個表示式介面、該介面解釋一個特定的上下文。主要對於一些固定文法構建一個解釋句子的直譯器。
直譯器模式介紹
一、來由
在軟體系統中,如果有一些特殊的領域問題較為複雜,疑似的模式不斷重複出現。這樣使用一般的程式設計方式會使程式編碼極為頻繁。在這樣的情況下,將這種特定的領域的問題轉換表達為某種語法規則的句子。構建一個直譯器來解釋這樣的句子、從而可以達到解決問題的目的。
二、意圖
給定一個語言,定義它的文法表示,並定義一個直譯器,這個直譯器使用該標識來解釋語言中的句子。
三、案例圖
四、直譯器模式程式碼示例
看上面的案例圖,我們一起看下其中包含的五個部分內容:
抽象表示式:定義直譯器介面、約定的操作。其中Interpret介面專門用來實現直譯器的功能
終結符表示式:實現抽象表示式要求的介面、文法中每一個終結符都有其對應的具體終結表示式。
非終結表示式:文法中每一個規則都需要一個具體的非終結符表示式、一般表示文法中的運算子或者一些關鍵字。
上下文類:這個角色用來存放終結符對應的具體的位置。
客戶端:指使用直譯器的客戶端。
我們看看這麼一個案例,在日常的程式開發中偶爾會遇到中文轉阿拉伯數字。對於一些運算需要中文轉數字計算。我們看看這一問題如何解決吧:
namespace Interpreter_Pattern { class InterpreterPattern { } /// <summary> /// Context: 環境類 /// </summary> public class Context { private string _statement; public Context(string statement) { this._statement = statement; contextMap.Add("一", 1); contextMap.Add("二", 2); contextMap.Add("三", 3); contextMap.Add("四", 4); contextMap.Add("五", 5); contextMap.Add("六", 6); contextMap.Add("七", 7); contextMap.Add("八", 8); contextMap.Add("九", 9); } public string Statement { get { return this._statement; } set { this._statement = value; } } public Dictionary<string, int> contextMap = new Dictionary<string, int>(); } /// <summary> /// AbstractExpression: 抽象表示式 /// </summary> public abstract class AbstractExpression { public abstract void Interpret(Context context); } public class TerminalExpression : AbstractExpression { public override void Interpret(Context context) { if (context.Statement!=null) { foreach (var Key in context.contextMap.Keys) { if (context.Statement.Contains(Key)) { context.Statement= context.Statement.Replace(Key, context.contextMap[Key].ToString());// context.contextMap[Key]); } } } //return context; } } public class NonterminalExpression : AbstractExpression { public override void Interpret(Context context) { if (context.Statement.Contains("加")) { context.Statement= context.Statement.Replace("加","+"); } if (context.Statement.Contains("減")) { context.Statement= context.Statement.Replace("減", "-"); } if (context.Statement.Contains("乘")) { context.Statement= context.Statement.Replace("乘", "*"); } if (context.Statement.Contains("除")) { context.Statement= context.Statement.Replace("除", "/"); } //return context; } } }
namespace Interpreter_Pattern { class Program { static void Main(string[] args) { Context context = new Context("三加八加九減二乘五除三"); AbstractExpression abstractExpression = new TerminalExpression(); abstractExpression.Interpret(context); AbstractExpression noabstractExpression = new NonterminalExpression(); noabstractExpression.Interpret(context); Console.WriteLine(context.Statement); } } }
使用場景及優缺點
一、使用場景
1、可以將一個需要解釋執行的語言中的句子表示為一個抽象語法樹。
2、一些重複的問題可以使用一種簡單的語言進行表達。
3、語言的文法較為簡單的時候可以考慮
二、優點
1、可擴充套件性高、比較靈活。
2、增加了新的解釋表示式的方式較為方便。
3、容易實現簡單的文法。
三、缺點
1、可利用場景少。
2、對於複製的文法維護較為困難。
3、直譯器模式會引起類的膨脹。
總結
到這裡我們就看完了直譯器模式,其實我們仔細想想正則表示式是不是也有點相似呢?正則表示式也是一個典型的直譯器。直譯器模式也就是給定一個語言,定義表示和直譯器。然後用這個直譯器來解釋語言中的句子。直譯器模式在平常的運用中較少、一般多用於表示式計算或者編譯器、SQL語句解析等。到這裡我們已經介紹完了23種設計模式。我們可以通過這個系列開頭的文章進行一個整體的回顧。
用愛生活,你會使自己幸福!用愛工作,你會使很多人幸福!
C#設計模式系列目錄
歡迎大家掃描下方二維碼,和我一起踏上設計模式的闖關之路吧!
&n