1. 程式人生 > >通俗易懂設計模式解析——直譯器模式

通俗易懂設計模式解析——直譯器模式

前言

  今天我們來講直譯器模式【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