天天看点

极速理解设计模式系列: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

继续阅读