面向对象编程思想-解释器模式

Posted 快跑啊兔兔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象编程思想-解释器模式相关的知识,希望对你有一定的参考价值。

一、引言

我们常常在会在字符串中搜索匹配字符或判断一个字符串是否符合我们要的格式时,使用正则表达式,可解决问题的背后是一种什么思想呢?即我们今天要学习的内容,解释器模式

二、解释器模式

定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

1.文法:即语法规则。在解释器模式中每一个语法都对应一个解释器对象,用来处理相应的语法规则。它对于扩展、改变文法规则都很方便

2.可以通过抽象语法树(Abstract Syntax Tree,AST)的图形方式来直观的表示语言的构成,每一棵抽象语法树对应一个语言实例

下面是解释器模式的结构图

下面是代码demo:

     abstract class Expression
    {
        public void Interpret(PlayContext context)
        {
            if(context.PlayText.Length==0)
            {
                return;
            }
            else
            {
                string playKey = context.PlayText.Substring(0, 1);
                context.PlayText = context.PlayText.Substring(2);
                double playValue = Convert.ToDouble(context.PlayText.Substring(0, context.PlayText.IndexOf(" ")));
                context.PlayText = context.PlayText.Substring(context.PlayText.IndexOf(" ")+1);
                Excute(playKey, playValue);
            }
        }
        public abstract void Excute(string key,double value);
    }
     class Note : Expression
    {
        public override void Excute(string key, double value)
        {
            string note = "";
            switch (key)
            {
                case "C":
                    note = "1";
                    break;
                case "D":
                    note = "2";
                    break;
                case "E":
                    note = "3";
                    break;
                case "F":
                    note = "4";
                    break;
                case "G":
                    note = "5";
                    break;
                case "A":
                    note = "6";
                    break;
                case "B":
                    note = "7";
                    break;
            }
            Console.Write(note);
        }
    }
    class Scale : Expression
    {
        public override void Excute(string key, double value)
        {
            string scale = "";
            switch (Convert.ToInt32(value))
            {
                case 1:
                    scale = "低音";
                    break;
                case 2:
                    scale = "中音";
                    break;
                case 3:
                    scale = "高音";
                    break;
            }
            Console.Write(scale);
        }
    }
    //演奏内容
    class PlayContext
    {
        //演奏文本
        private string text;
        public string PlayText
        {
            get { return text; }
            set { text = value; }
        }
    }
     class Program
    {
        static void Main(string[] args)
        {
            PlayContext playContext = new PlayContext();
            Console.WriteLine("上海滩");
            playContext.PlayText = "O 1 E 2 C 0.5 D 2 A 5 G 0.5 P 2 P 0.5 O 2 E 2 O 3 C 0.5 E 2 C 1 ";
            Expression expression = null;
            try
            {
                while (playContext.PlayText.Length>0)
                {
                    string str = playContext.PlayText.Substring(0, 1);
                    switch (str)
                    {
                        case "O":
                            expression = new Scale();
                            break;
                        case "C":
                        case "D":
                        case "E":
                        case "F":
                        case "G":
                        case "A":
                        case "B":
                        case "P":
                            expression = new Note();
                            break;
                    }
                    expression.Interpret(playContext);
                }
            }
            catch (Exception ex )
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
View Code

代码demo2:

    class ChineseEnglishDict
    {
        private static Dictionary<string, string> _dictionary = new Dictionary<string, string>();
        static ChineseEnglishDict()
        {
            _dictionary.Add("this", "");
            _dictionary.Add("is", "");
            _dictionary.Add("an", "一个");
            _dictionary.Add("apple", "苹果");
        }
        public static string GetEnglish(string value)
        {
            return _dictionary[value];
        }
    }
    //定义AbstractExpression接口
    interface IExpression
    {
        void Interpret(StringBuilder sb);
    }
    //定义具体的Expression,这里包括对英文单词的翻译和英文句号的翻译
    class WordExpression : IExpression
    {
        private string _value;
        public WordExpression(string value)
        {
            this._value = value;
        }
        public void Interpret(StringBuilder sb)
        {
            sb.Append(ChineseEnglishDict.GetEnglish(_value.ToLower()));
        }
    }
     //对英文句号的翻译
    class SymbolExpression : IExpression
    {
        private string _value;
        public SymbolExpression(string value)
        {
            this._value = value;
        }
        public void Interpret(StringBuilder sb)
        {
            switch (_value)
            {
                case ".":
                    sb.Append("");
                    break;
            }
        }
    }
    //将解释器组合起来包装,方便外部调用
    public static class Translator
    {
        public static string Translate(string sentense)
        {
            StringBuilder sb = new StringBuilder();
            IList<IExpression> expressions = new List<IExpression>();
            string[] elements = sentense.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);
            }
            return sb.ToString();
        }
    }
     class Program
    {
        static void Main(string[] args)
        {
            string english = "This is an Apple";
            string chinese = Translator.Translate(english);
            Console.WriteLine(chinese);
            Console.Read();
        }
    }
View Code

优点:

1.易于实现文法。一条语法规则用一个解释器来解释执行,解释器只需要考虑这一条语法规则的实现就可以了

2.易于扩展新的语法。可以通过继承等方式创建相应的解释器对象

缺点:

1.执行效率低。解释器模式中使用了大量的循环或递归调用

2.对于复杂文法难以维护。每一条规则至少需要定义一个类,如果一个语言包含太多的文法规则,类的过程会急剧增加,导致系统难以管理和维护

适用场景:

1.当一个语言需要解释执行,并可以将语言中的句子表示为一个抽象的语法树的时候

2.一些重复出现的问题可以用一种简单的语言表达

3.一个语言的文法较为简单

4.当执行效率不是关键和主要关心的问题

 

参考:

大话设计模式;

http://www.cnblogs.com/5iedu/p/5595153.html

以上是关于面向对象编程思想-解释器模式的主要内容,如果未能解决你的问题,请参考以下文章

面向对象编程思想-简单工厂模式

面向对象编程思想-代理模式

面向对象编程思想-单例模式

JavaScript设计模式:面向对象编程(第二节)

VSCode自定义代码片段——JS中的面向对象编程

面向对象编程思想-组合模式