15.Interpreter解释器(行为型模式)
一、动机(Motivation)
<1>在软件构建过程中,如果某一特定领域的问题比较复杂,类似的模式不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
<2>在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。
二、意图(Intent)
给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。
——《设计模式》GoF
三、结构(Structure)
四、结构详解
五、生活中的例子
机器人,通过对它发出命令,它通过内置的解释器执行相应的动作。
<1>状态相关
S:启动
E:关机
<2>动作相关
L:左转
R:右转
F:前行
B:后退
六、实现
namespace Test
{public class 指令 //Context{private string _txt = "";public string 内容{get { return this._txt; }set { this._txt = value; }}}public abstract class 表达式{public abstract void 解释(指令 context);}public class 动作表达式 : 表达式{public override void 解释(指令 context){string key = context.内容.Substring(0, 1);string result = "";switch (key){case "F":result = "前进";break;case "B":result = "后退";break;case "L":result = "左转弯";break;case "R":result = "右转弯";break;}Console.WriteLine("执行动作:{0}", result);context.内容 = context.内容.Substring(1, context.内容.Length - 1);//指令减少}}public class 状态表达式 : 表达式{public override void 解释(指令 context){string key = context.内容.Substring(0, 1);string result = "";switch (key){case "S":result = "启动";break;case "E":result = "关机";break;}Console.WriteLine("状态改变:{0}", result);context.内容 = context.内容.Substring(1, context.内容.Length - 1);//指令减少}}public class 机器人{public void 执行命令(指令 context){表达式 expression = null;while (context.内容.Length > 0){string 当前命令 = context.内容.Substring(0, 1);if (当前命令 == "S" || 当前命令 == "E"){expression = new 状态表达式();}else{expression = new 动作表达式();}expression.解释(context);}}}internal class Program{static void Main(string[] args){机器人 robot = new 机器人();指令 command = new 指令();command.内容 = "SLRBFLLRRBBFFE";robot.执行命令(command);Console.ReadLine();}}
}
实现结果
七、实现要点
<1>TerminalExpression:
可明确的知道如何解释的表达式
如:“关机”
<2>NonterminalExpression:
多义的,需要根据具体情况才能进行最终解释的表达式
如:“你真有才”
<3>只适用于简单文法(表达式)
八、效果
<1>解释器模式提供了一个简单的方式来执行语法,而且容易修改或者扩展语法;
<2>一般系统中很多类使用相似的语法,可以使用一个解释器来代替为每一个规则实现一个解释器。而且在解释器中不同的规则是由不同的类来实现的,这样使得添加一个新的语法规则变得简单。
九、适用性
业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象为语法规则
十、总结
<1>使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
<2>Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interperter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。