C# 设计模式-解释器模式
一.介绍
解释器模式(Interpreter Pattern)。属于行为型模式。给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
二.实现
举个例子,有一个中英文翻译系统可以翻译一句英文的话,每个英文单词对应的是去翻译出中文,而标点符号输出的还是标点符号。
//抽象解释接口 public interface IExpression { void Interpret(StringBuilder sb); } //单词解释(非终结符解释) public class WordExpression : IExpression { private string _value; public WordExpression(string value) { _value = value; } public void Interpret(StringBuilder sb) { sb.Append(ChineseEnglishDict.GetEnglish(_value.ToLower())); } } //标点符号解释(终结符解释) public class SymbolExpression : IExpression { private string _value; public SymbolExpression(string value) { _value = value; } public void Interpret(StringBuilder sb) { switch (_value) { case ".": sb.Append("。"); break; } } } //容器(保存解释器中所对应的具体值) public static class ChineseEnglishDict { private static Dictionary<string, string> _dictory = new Dictionary<string, string>(); static ChineseEnglishDict() { _dictory.Add("this", "这"); _dictory.Add("is", "是"); _dictory.Add("an", "一个"); _dictory.Add("apple", "苹果"); } public static string GetEnglish(string value) { return _dictory[value]; } } //调用 public static void Main(string[] args) { string englist = "This is an apple."; StringBuilder sb = new StringBuilder(); List<IExpression> expressions = new List<IExpression>(); string[] elements = englist.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); foreach (string element in elements) { string[] words = element.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); foreach (string word in words) { expressions.Add(new WordExpression(word)); } expressions.Add(new SymbolExpression(".")); } foreach (IExpression expression in expressions) { expression.Interpret(sb); } Console.WriteLine(sb.ToString()); }
三.总结
优点:
1.易于改变和拓展文法。
2.每一条文法规则都可以表示为一个类,因此可以方便实现一个简单的语言。
3.实现文法较为容易。在抽象语法书中每一个表达式节点类的实现方式都是相似的,这些类的代码编写都不会太复杂,还可以通过一些工具自动生成节点类代码。
4.增加新的解释表达式较为方便。如果用户需要增加新的解释表达式只需要增加一个新的终结符表达式或非终结符表达式即可,原有表达式类无须修改,符合开闭原则。
缺点:
1.对于复杂文法难以维护。在解释器模式中,每一条规则至少定义一个类,因此如果一个语言包含了太多文法规则,类的个数会增加,导致系统难以维护和管理,此时可以考虑使用语法分析程序等方式来取代解释器模式。
2.执行效率较低。由于在解释器模式中使用了大量循环和递归,因此在解释较为复杂的句子时运行速度会较慢,而且代码的调试过程也比较复杂。