天天看點

極速了解設計模式系列:24.解釋器模式(Interpreter Pattern)

五個角色:場景(Context)、抽象表達式(Component)、終結符表達式(TerminalExpression)、非終結符表達式(NonterminalExpression)、用戶端(Client) 

        場景(Context):解釋器的全局資訊

        抽象表達式(Component):定義一個接口來解釋操作

        終結符表達式(TerminalExpression):直接跳過步驟,不用解釋語句

        非終結符表達式(NonterminalExpression):根據規則實作解釋操作

        用戶端(Client):調用解釋器,對語句進行解釋。

實作思路:建立文法樹,然後用文法将表達式進行解析。

類圖: 

<a target="_blank" href="http://blog.51cto.com/attachment/201204/180452274.gif"></a>

應用場景:将十六進制值解釋為十進制。

分析:如果以0X開頭則将十六進制解釋為十進制,否則直接輸出的就是十進制不需要解釋。

        下面我們在控制台程式去示範一下如何使用Interpreter Pattern:

        一、 場景(Context)

//場景(Context) 

  class Context 

  { 

      public Context(string input) 

      { 

          this.Input = input; 

      } 

      /// &lt;summary&gt; 

      /// 輸入參數 

      /// &lt;/summary&gt; 

      public string Input { get; set; } 

      /// 輸出參數 

      public int Output { get; set; } 

      /// 是否是十六進制 如果是轉為十進制,否則不轉 

      public bool Status { get; set; } 

  } 

        二、抽象表達式(Component)

//抽象表達式類(AbstractExpression) 

abstract class Expression 

    public virtual void Interpret(Context context) 

    { 

        if (context.Input.Length == 0) 

            return; 

        int multiresult = Multiplier(context); 

        if (multiresult == 0) 

        if(context.Input.StartsWith("F")) 

        { 

            context.Output += (15 * multiresult); 

            context.Input=context.Input.Substring(1); 

        } 

        else if (context.Input.StartsWith("F")) 

            context.Input = context.Input.Substring(1); 

        else if (context.Input.StartsWith("E")) 

            context.Output += (14 * multiresult); 

        else if (context.Input.StartsWith("D")) 

            context.Output += (13 * multiresult); 

        else if (context.Input.StartsWith("C")) 

            context.Output += (12 * multiresult); 

        else if (context.Input.StartsWith("B")) 

            context.Output += (11 * multiresult); 

        else if (context.Input.StartsWith("A")) 

            context.Output += (10 * multiresult); 

        else 

            context.Output += (int.Parse(context.Input.Substring(0, 1)) * multiresult); 

    } 

    //該位置需要做的乘法值 

    public abstract int Multiplier(Context context); 

        三、終結符表達式(TerminalExpression)

//終結符表達式(TerminalExpression) 

 class NumterminalExp : Expression 

 { 

     public override void Interpret(Context context) 

     { 

         if (context.Input.StartsWith("0X")) 

         { 

             context.Input = context.Input.Substring(2); 

             context.Status = true; 

         } 

         else 

         {  

             context.Output = int.Parse(context.Input); 

             context.Status = false; 

             return; 

     } 

     public override int Multiplier(Context context) 

         return 1; 

     }  

 } 

        四、非終結符表達式(NonterminalExpression)

//非終結符表達式(NonterminalExpression)  千位計算 

class ThousandExp : Expression 

    public override int Multiplier(Context context) 

        if (context.Input.Length == 4&amp;&amp;context.Status) 

            return 16 * 16 * 16; 

            return 0; 

//非終結符表達式(NonterminalExpression)  百位計算 

class HundredExp : Expression 

        if (context.Input.Length == 3 &amp;&amp; context.Status) 

            return 16 * 16; 

//非終結符表達式(NonterminalExpression)  十位計算 

class TenExp : Expression 

        if (context.Input.Length == 2 &amp;&amp; context.Status) 

            return 16; 

//非終結符表達式(NonterminalExpression)  個位計算 

class OneExp : Expression 

        if (context.Input.Length == 1 &amp;&amp; context.Status) 

            return 1; 

        五、用戶端(Client)

//用戶端(Client) 

class Program 

    static void Main(string[] args) 

        string input = "0XA321"; 

        Context context = new Context(input.ToUpper()); 

        List&lt;Expression&gt; expTree = new List&lt;Expression&gt;(); 

        expTree.Add(new NumterminalExp()); 

        expTree.Add(new ThousandExp()); 

        expTree.Add(new HundredExp()); 

        expTree.Add(new TenExp()); 

        expTree.Add(new OneExp()); 

        foreach (Expression exp in expTree) 

            exp.Interpret(context);     

        Console.WriteLine("十六進制數{0}轉換為十進制數{1}", input, context.Output); 

        Console.ReadLine(); 

本文轉自程興亮 51CTO部落格,原文連結:http://blog.51cto.com/chengxingliang/827101

繼續閱讀