概述:
GOF定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
在软件开发特别是DSL开发中常常需要使用一些相对较复杂的业务语言,如果业务语言使用频率足够高,且使用普通的编程模式来实现会导致非常复杂的变化,那么就可以考虑使用解释器模式构建一个解释器对复杂的业务语言进行翻译。
这种做法虽然效率相对较低,但可以允许用户使用自定义的业务语言来处理逻辑,因此在效率不是关键问题的场合还是较为有用的。
1. context:包含解释器之外的一些全局信息。解释器上下文环境类,用来存储解释器的上下文环境,比如需要解释的文法等。
2. 终结符表达式角色:具体表达式。实现与文法中的终结符相关联的解释操作。句子中的每个终结符需要该类的一个实例与之对应。
3. 非终结符表达式角色:具体表达式。文法中的每条规则R=R1R2…Rn都需要一个非终结符表达式角色。对于从R1到Rn的每个符号都维护一个抽象表达式角色的实例变量。实现解释操作,解释一般要递归地调用表示从R1到Rn的那些对象的解释操作。
4. 客户角色:构建(或者被给定)表示该文法定义的语言中的一个特定的句子的抽象语法树,调用解释操作。
举一个加减乘除运算解释器例子,代码如下:
1.Context 类:
public class Context { //private Dictionary<string, int> dic = new Dictionary<string, int>(); //public void AddValue(string variable, int value) //{ // dic.Add(variable, value); //} //public int GetValue(string variable) //{ // if (dic.ContainsKey(variable)) // { // return dic[variable]; // } // return 0; //} }
因为我后续没有用到,就把这里面的代码注释掉了,这里可以根据需要在增加代码,一般用例储存上下文的环境等。
2.接口Expression
public interface Expression { int Interpreter(Context ctx); }
3.变量表达式 Variable
public class Variable : Expression { public int value { get; set; } public Variable(int value) { this.value = value; } public int Interpreter(Context ctx) { return this.value; } }
4.常量表达式
//常量 public class ConstantExpression : Expression { private int i; public ConstantExpression(int i) { this.i = i; } public int Interpreter(Context ctx) { return i; } }
5.增加表达式
public class AddExprestion : Expression { private Expression left, right; public AddExprestion(Expression left, Expression right) { this.left = left; this.right = right; } public int Interpreter(Context ctx) { return left.Interpreter(ctx) + right.Interpreter(ctx); } }
6.减法表达式
public class SubtractExprestion : Expression { private Expression left, right; public SubtractExprestion(Expression left, Expression right) { this.left = left; this.right = right; } public int Interpreter(Context ctx) { return left.Interpreter(ctx) - right.Interpreter(ctx); } }
7. 测试运行
static void Main(string[] args) { Context ctx = new Context(); Variable a = new Variable(1); Variable b = new Variable(2); Expression addExp = new SubtractExprestion(new ConstantExpression(10), new AddExprestion(b, a)); int result = addExp.Interpreter(ctx); Console.WriteLine("result=(10-(1+2))=" + result); }
8. 运行结果
最后,用过C#就知道里面的LambdaExpression 设计思想是解释器模式最好的解释。