• 解释器模式


    定义

    建立一个解释器解释程序的逻辑与业务。也就是将一个比较复杂的业务分解成语法树或者是逻辑树。

    类图

    代码

      1 /// <summary>
      2     /// 抽象表达式
      3     /// </summary>
      4     public abstract class Expression
      5     {
      6         public abstract int Interprete(Dictionary<string, int> dicParameters);
      7     }
      8     /// <summary>
      9     /// 变量表达式(变量)
     10     /// </summary>
     11     public class VarExpress : Expression
     12     {
     13         private string key;
     14         public VarExpress(string key)
     15         {
     16             this.key = key;
     17         }
     18         public override int Interprete(Dictionary<string, int> dicParameters)
     19         {
     20             if (dicParameters.ContainsKey(key))
     21             {
     22                 return dicParameters[key];
     23             }
     24             else
     25             {
     26                 throw new Exception(string.Format("{0} is not avaliable", key));
     27             }
     28         }
     29     }
     30     /// <summary>
     31     /// 计算符号表达式
     32     /// </summary>
     33     public abstract class SymbolExpress : Expression
     34     {
     35         protected Expression leftExpression;
     36         protected Expression rightExpression;
     37         public SymbolExpress(Expression left, Expression right)
     38         {
     39             leftExpression = left;
     40             rightExpression = right;
     41         }
     42     }
     43     /// <summary>
     44     /// 加法表达式
     45     /// </summary>
     46     public class AddExpress : SymbolExpress
     47     {
     48         public AddExpress(Expression left, Expression right) : base(left, right)
     49         {
     50 
     51         }
     52         public override int Interprete(Dictionary<string, int> dicParameters)
     53         {
     54             return leftExpression.Interprete(dicParameters) + rightExpression.Interprete(dicParameters);
     55         }
     56     }
     57     /// <summary>
     58     /// 减法表达式
     59     /// </summary>
     60     public class SubExpress : SymbolExpress
     61     {
     62         public SubExpress(Expression left, Expression right) : base(left, right)
     63         {
     64 
     65         }
     66         public override int Interprete(Dictionary<string, int> dicParameters)
     67         {
     68             return leftExpression.Interprete(dicParameters) - rightExpression.Interprete(dicParameters);
     69         }
     70     }
     71     /// <summary>
     72     /// 计算器
     73     /// </summary>
     74     public class Calculator
     75     {
     76         private Expression expression;   //表达式
     77 
     78         public Calculator(String expressionString)
     79         {
     80             Stack<Expression> stack = new Stack<Expression>();
     81 
     82             char[] charArray = expressionString.ToCharArray();
     83 
     84             Expression left = null;
     85 
     86             Expression right = null;
     87 
     88             for (int i = 0; i < charArray.Length; i++)
     89             {
     90 
     91                 switch (charArray[i])
     92                 {
     93 
     94                     case '+': //加法
     95 
     96                         //加法结果放到堆栈中
     97 
     98                         left = stack.Pop();
     99 
    100                         right = new VarExpress((charArray[++i]).ToString());
    101 
    102                         stack.Push(new AddExpress(left, right));
    103 
    104                         break;
    105 
    106                     case '-':
    107 
    108                         left = stack.Pop();
    109 
    110                         right = new VarExpress((charArray[++i]).ToString());
    111 
    112                         stack.Push(new SubExpress(left, right));
    113 
    114                         break;
    115                     //当然还有乘法/除法等
    116                     default: //默认就是变量
    117                         stack.Push(new VarExpress((charArray[i]).ToString()));
    118                         break;
    119 
    120                 }
    121 
    122             }
    123             this.expression = stack.Pop();
    124 
    125         }
    126 
    127         /// <summary>
    128         /// 计算
    129         /// </summary>
    130         /// <param name="parameters"></param>
    131         /// <returns></returns>
    132         public int Run(Dictionary<String, int> parameters)
    133         {
    134             return this.expression.Interprete(parameters);
    135 
    136         }
    137 
    138     }

    调用部分

     1  class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5             Calculator c = new Calculator("a+b-c");
     6             Dictionary<string, int> dic = new Dictionary<string, int>();
     7             dic.Add("a", 100);
     8             dic.Add("b", 10);
     9             dic.Add("c", 20);
    10             int result = c.Run(dic);
    11             Console.WriteLine(result.ToString());
    12             Console.ReadLine();
    13         }
    14     }

    总结

    计算表达式就是一个非常经典的解释器模式的体现。当然像语法的解析、表达式的解析等引入解释器模式大大方便了实现与理解。像例子中的加减运算的实现,通过定义加减运算表达式和变量表达式,再通过栈的临时存储,很好的实现了通过解释给出的表达式,而实现计算的效果。当然当看到变量表达式是叶子节点,而运算表达式却相当于枝节点,怎么跟组合表达式有些类似呢?最终还是回到设计模式的关键点,还是他们关注点不一样,组合在于包含组成,他的组成方式可能是集合,而且它更多的体现的包含关系。而解释器在于解释,是一种行为。通过自身内部的迭代解释得出最终的运算,并得出结果。

    其实,解释器用得还是比较少的,感觉蛮高大上的。

    Top
    收藏
    关注
    评论
  • 相关阅读:
    configure: error: no acceptable cc found in $PATH
    SQL server的错误日志导致服务器C盘满
    域名/IP 正则表达式
    rpm 基本命令
    VB TO C#
    yum 的基本操作
    在服务器上怎么检查一个网站的在线连接数有多大。
    MSSQL2005不能连接远程有非法字符密码的数据库
    按账目类型和日期查看账目
    梦断代码读书笔记(二)
  • 原文地址:https://www.cnblogs.com/Joy-et/p/4912780.html
Copyright © 2020-2023  润新知