解释器模式(Interpreter):
从名称上来看看这个模式,个人的最初理解“解释器”和Google的中英翻译功能类似。如果有一天你去国外旅游去了,比如去美国吧,美国人是讲英语的,我们是讲汉语的,如果英语听不懂,讲不好,估计沟通就完蛋了,不能沟通,估计玩的就很难尽兴了,因为有很多景点的解说你可能不明白(没有中文翻译的情况下,一般情况会有的)。所以我们需要一个软件,可以把中英文互译,那彼此就可以更好的理解对方的意思,我感觉翻译软件也可以称得上是解释器,把你不懂的解释成你能理解的。我们写代码,需要编译器把我们写的代码编译成机器可以理解的机器语言,从这方面来讲,C#的编译器也是一种解释器。
解释器模式的角色:
1)抽象解释器(AbstractExpression):定义解释器的接口,约定解释器的解释操作。其中的Interpret接口,正如其名字那样,它是专门用来解释该解释器所要实现的功能。
2)终结符表达式(TermialExpression):实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
3)非终结符表达式(NonterminalExpression):文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。
4)环境角色(Context):这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。
我们演示一个判断且或的例子。
1 public abstract class AbstractExpression 2 { 3 public abstract bool Interpret(string context); 4 } 5 6 public class TerminalExpression : AbstractExpression 7 { 8 private string data; 9 10 public TerminalExpression(string data) 11 { 12 this.data = data; 13 } 14 15 public override bool Interpret(string context) 16 { 17 return data.Contains(context); 18 } 19 } 20 21 public class OrExpression : AbstractExpression 22 { 23 private AbstractExpression expr1 = null; 24 private AbstractExpression expr2 = null; 25 26 public OrExpression(AbstractExpression expr1, AbstractExpression expr2) 27 { 28 this.expr1 = expr1; 29 this.expr2 = expr2; 30 } 31 32 public override bool Interpret(string context) 33 { 34 return expr1.Interpret(context) || expr2.Interpret(context); 35 } 36 } 37 38 public class AndExpression : AbstractExpression 39 { 40 private AbstractExpression expr1 = null; 41 private AbstractExpression expr2 = null; 42 43 public AndExpression(AbstractExpression expr1, AbstractExpression expr2) 44 { 45 this.expr1 = expr1; 46 this.expr2 = expr2; 47 } 48 49 public override bool Interpret(string context) 50 { 51 return expr1.Interpret(context) || expr2.Interpret(context); 52 } 53 } 54 55 public class Program 56 { 57 //规则:Robert 和 John 是男性 58 public static AbstractExpression GetMaleExpression() 59 { 60 AbstractExpression robert = new TerminalExpression("Robert"); 61 AbstractExpression john = new TerminalExpression("John"); 62 return new OrExpression(robert, john); 63 } 64 65 //规则:Julie 是一个已婚的女性 66 public static AbstractExpression GetMarriedWomanExpression() 67 { 68 AbstractExpression julie = new TerminalExpression("Julie"); 69 AbstractExpression married = new TerminalExpression("Married"); 70 return new AndExpression(julie, married); 71 } 72 73 public static void Main(string[] args) 74 { 75 AbstractExpression isMale = GetMaleExpression(); 76 AbstractExpression isMarriedWoman = GetMarriedWomanExpression(); 77 78 Console.WriteLine($"John is male? {isMale.Interpret("John")}"); 79 Console.WriteLine($"Julie is a married women? {isMarriedWoman.Interpret("Married Julie")}"); 80 } 81 }
这里我们可以得出:解释器模式有很好的扩展模式,或此时我们希望能够找到一位男士已婚,我们只需要再写一个非终结符表达式即可,易于扩展。我们再来看下面这个例子。
1 // 抽象表达式 2 public abstract class Expres