设计模式之------解释器模式(Interpreter Pattern )

一、概念

①、什么是解释器模式?

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

②、主要解决什么问题?

        对于一些固定文法构建一个解释句子的解释器。

③、如何解决?

       构建语法树,定义终结符与非终结符

④、何时使用?

        如果一种特定类型的问题发生的频率足够高,那么可能就值得该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。

⑤、使用场景?

       1、可以将一个需要解释执行的语言中的句子表示为一个抽象的语法树。

       2、一些重复出现的问题可以用一种简单的语言来进行表达。

       3、一个简单语法需要解释的场景。

⑥、优缺点?

优点: 1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。

缺点: 1、可利用场景比较少。 2、对于复杂的文法比较难维护。 3、解释器模式会引起类膨胀。 4、解释器模式采用递归调用方法。

二、图

①、结构图

②、拓展图

大话设计模式中的老板与小菜

 大话设计模式中的上海滩演奏

三、代码

①、代码类图

②、代码

客户端类

class Program
    {
        static void Main(string[] args)
        {
            PlayContext context = new PlayContext();   //实例化一个演奏内容
            Console.WriteLine("上海滩:");              //在控制台上写入内容
            //演奏的文本
            context.PlayText = "O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3 ";
            Expression expression = null;              //用表达式类实例化出一个表达式对象
            try
            {
                while(context.PlayText.Length>0)       //当演奏中文本长度大于0时
                {
                    string str = context.PlayText.Substring(0, 1);   //截取演奏文本内容,从index 0 开始,截取一个,即对得出Str=O
                    switch(str)                        //选择分支
                    {
                        case "O":                      //当str=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(context);      //调取表达式对象的解释方法,将演奏的内容传过去           
                }
            }
            catch(Exception ex)                         //如果出错
            {
                Console.WriteLine(ex.Message);          //在控制台上写入出错解释
            }
            Console.Read();
        } 
    }

演奏内容类

 //演奏内容类
    class PlayContext
    {

        //演奏文本
        private string text;
        public string PlayText
        {
            get { return text;}
            set { text = value; }
        }
    }

表达式类(解释器)

//表达式类
    abstract class Expression
    {
        //解释器
        public void Interpret(PlayContext context)
        {
            if(context.PlayText.Length==0)                           //如果演奏文本的内容为空,则返回
            {
                return;
            }
            else
            {   
                string playKey = context.PlayText.Substring(0, 1);    //定义一个字符串变量,来承接从演奏文本中截取的内容,第一次内容为:O
                context.PlayText = context.PlayText.Substring(2);     //Substring重载,读取演奏文本index2 之后的内容,第一次内容为从2往后的所有内容
                double playValue = Convert.ToDouble(context.PlayText.Substring(0, context.PlayText.IndexOf(" "))); //定义一个双精度变量,来承接从更新的演奏文本中截取的内容,从index0 开始截取context.PlayText.IndexOf(" ")=1个
                context.PlayText = context.PlayText.Substring(context.PlayText.IndexOf(" ") + 1);//读取演奏文本index(空格索引+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":                        //如果获得的Key是C则演奏1(do)
                    note = "1";
                    break;
                case "D":                       //如果获得的Key是D则演奏2(Re)
                    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("{0} ", note);
        }
    }

音阶类

 //音阶类
    class Scale : Expression
    {
        public override void Excute(string key, double value)  //重写父类的演奏方法
        {
            string scale = "";
            switch (Convert.ToInt32(value))                   //将传递过来的value值转换为整数
            {
                case 1:                                       //如果获得的Key是O并且value是1,则演奏低音
                    scale = "低音";
                    break;
                case 2:                                       //如果获得的Key是O并且value是1,则演奏中音
                    scale = "中音";
                    break;
                case 3:
                    scale = "高音";
                    break;
            }
            Console.Write("{0}", scale);                     //在控制台内写入音阶内容
        }
    }

四、拓展

https://blog.csdn.net/niunai112/article/details/79982712

以上便是解释器的梳理,回顾会品出不一样的味道,下一站走起^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elsa~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值