个人感受

  我知道,会在csdn博客里面来寻关于这个模式的文章,一般是自学的人,还有就是,看了这个设计模式,十脸蒙逼的人,我也是属于后者,但是只要肯下功夫,就一定能够搞懂,因为这个世界上最怕认真二字。

解释器模式的定义

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

解释器模式存在的角色

以是大话设计模式总结的几个角色

  1. 抽象表达式(AbstractExpression):抽象表达式,声明一个抽象的解释操作,这个接口是被抽象语法树中所有节点共享 。在具体代码的地方再来讲解的)
  2. 上下文(Context):包含解释以外的其他全局信息。
  3. 终结符表达式(TerminalExpression):实现与文法中的终结符相关联的解释操作。
  4. 非终结符表达式(NonTerminalExpression):实现与文法中的非终结符的解释操作,对应的是文法中的每一条规则的都需要一个具体的非终结符表达式类。
  5. 最后呢就是客户端(Client):就是写的主函数。

解释器模式的UML类图


上海滩简谱:
针对于上面的简谱,程序是不能区分的,所有需要文法来定义,然后再翻译,在我下面的代码中就已经通过定义的文法去表示出了上海滩简谱的文本表示。

具体代码实现(定义的文法和代码实现)

在大话设计模式这本书中,他定义了一个用来解释音乐的一种文法,原文如下:
“现在我定了一套提则,和QB的有点类似,但为了简便起见,我做了改动,你就技我定义的规则来
我的规则是O表示音阶
O1”表示低音阶,*O2’ 表示中音阶,O3’表示高音阶: ‘P”表
示休止符,
C D E F G A B表示“Do-Re-Mi-Fa-So-La-T’: 音符长度1表示一拍,2表示二拍,0.5
表示半拍,0.25表示四分之一拍以此类推:注意:所有的字母和数字都要用半角空格分开。例如上海滩的歌曲第一句‘浪奔‘可以写成"O 2 E 0.5 G 0.5 A 3"按照文法来解释就是O表示是音阶,2表示中音,E表示是音符Mi,0.5表示音符Mi要唱半拍,G表示音符So,0.5表示音符So要唱半拍,A表示音符La,3表示音符La要唱3拍。你再去对照那个简谱去看一看,是不是一样的。
其实也可以想一想,一个音乐要产生,那他会由什么组成呢,音阶,音符,节拍等一些东西组成,而音阶,音符,节拍就是要产生一个音乐的各种文法,音阶有低音,中音,高音(非专业人士,只能这样简单的去区分,况且我们的着眼点是代码,不是这些)音符就有1234567这些,而且还有音符所要演唱的节拍长度。这些也对应于上面所说的非终结符表达式,context就是我们的所有符合我们定义的文法的句子的文章,里面包含了很多的句子,需要通过解释器去翻译,我们就是去将文章中的句子一个一个取出来去翻译给机器去执行,让他按照我们定义的文法去发出声音。

以下是我的代码(与设计模式的书上有些不同,稍微改了一下,设计模式的书是基于C++写的,我是基于java写的,差别不大)

package com.cduestc.pattern.interpreter;
/*** 解释器模式* 把一个语言解释为目标对象能看得懂的语言* @author naic*substring(0,1)截取字符串,从第一个字母开始,到第二个字母结束,左闭右开*substring(2)截取字符串,从第三个字母开始截取,包括第三个字母以及后面的所有字符一起返回,*返回的是字符串,*/
public class Client {public static void main(String[] args) {PlayContext context=new PlayContext();context.setText("O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 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;while(context.getText().length()>0){String str=context.getText().substring(0, 2).trim();switch (str) {case "O":expression=new Scale();break;case "C":case "D":case "E":case "F":case "G":case "A":case "B":expression=new Note();break;}expression.interpret(context);}}}
//演奏文本类
class PlayContext
{private String text;public String getText() {return text;}public void setText(String text) {this.text = text;}
}//表达式类
abstract class Expression
{protected String playKey;protected String playValue;//解释器public void interpret(PlayContext playContext){if(playContext.getText().length()==0){return ;}else{String playKey=playContext.getText().substring(0,2).trim();//获取当前文本的前一个字母playContext.setText(playContext.getText().substring(2));//将已经翻译了的截取出去。String playValue=playContext.getText().substring(0,playContext.getText().indexOf(" ")).trim();playContext.setText(playContext.getText().substring(playContext.getText().indexOf(" ")+1));excute(playKey, playValue);}}  public abstract void excute(String playKey,String playValue);
}
//音符类
class Note extends Expression
{public void excute(String playKey, String playValue) {switch(playKey){case"C":this.playKey="1";break;case"D":this.playKey="2";break;case"E":this.playKey="3";break;case"F":this.playKey="4";break;case"G":this.playKey="5";break;case"A":this.playKey="6";break;case"B":this.playKey="7";break;}switch(playValue){case"0.5":this.playValue="半拍";break;case"1":this.playValue="一拍";break;case"1.5":this.playValue="一拍半";break;case"2":this.playKey="两拍";break;}System.out.print("("+this.playKey+","+this.playValue+")");}}
//音阶类
class Scale extends Expression
{@Overridepublic void excute(String playKey, String playValue) {//System.out.println(playKey+playValue);switch (playKey) {case "O":this.playKey="音阶";break;}switch (playValue) {case "1":this.playValue="低音";break;case "2":this.playValue="中音";break;case "3":this.playValue="高音";break;}System.out.print("("+this.playKey+","+this.playValue+")");}
}

我来解释以下我的上面的代码

1.Expression:(抽象表达式类):里面定义了一个具体的interpret方法,这个方法传入了一个PalyContext类的实例,也就是说Expression依赖与PlayContext,这个方法的作用就是将我们要演奏的音乐文本一句一句的取出来,然后,不同的文法类就会按照它所定义的文法去翻译。
2.音阶类:这里面就定义了具体怎么去翻译当前的这个音阶类的对象
3.音符类:这里面就定义了具体怎么去翻译当前的这个音符类的对象
4.客户端:取出一个一个的句子,然后判断是音阶类还是音符类,去生成不同的对象,解释不同的操作。

我来声明一下

这里只是为了理解解释器模式这个思想,肯定是不能发出声音的,要想发出声音,就涉及到硬件的调用了。最后其实解释器模式就是为了去翻译你所定义的满足你的文法的句子,然后让机器能够看懂要做什么。希望对看了这片文章的人有所帮助。个人观点,可以留言探讨,错误的地方还望指正,大神轻喷。

java设计模式之解释器模式相关推荐

  1. java 设计模式之解释器模式(十九)

    java 设计模式之解释器模式①⑨ 定义 角色分析 使用场景 代码实现 躁动的心灵,不安的灵魂.在彷徨中挣扎,在迷失中探索.时光飞逝,努力不变. 设计模式学习,近期我会把23种设计模式都写成博客,敬请 ...

  2. Java设计模式分为创建模式, 结构模式, 行为模式 3种类型

    Java设计模式之创建模式包括: Factory,    工厂模式 Singleton,   单例模式 Builder,    建造模式 Prototype,    原型模式 Java设计模式之结构模 ...

  3. java备忘录模式应用场景_图解Java设计模式之备忘录模式

    图解Java设计模式之备忘录模式 游戏角色状态恢复问题 游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态. ...

  4. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  5. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

    Java设计模式Ⅶ 1.访问者模式 1.1 访问者模式概述 1.2 代码理解 2.迭代器模式 2.1 迭代器模式概述 2.2 代码理解 3.观察者模式 3.1 观察者模式概述 3.2 代码理解 4.中 ...

  6. Java设计模式(建造者模式-适配器模式-桥接模式)

    Java设计模式Ⅲ 1.建造者模式 1.1 建造者模式概述 1.2 建造者模式的注意事项和细节 1.3 代码理解 2.适配器模式 2.1 类适配器模式 2.1.1 代码理解 2.2 对象适配器模式 2 ...

  7. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

  8. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  9. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  10. java设计模式5--原型模式(Prototype)

    本文地址:http://www.cnblogs.com/archimedes/p/java-prototype-pattern.html,转载请注明源地址. 原型模式 用原型实例指定创建对象的种类,并 ...

最新文章

  1. 使用pushMeBaby后台测试远程推送
  2. POJ 1932 XYZZY (差分约束+传递闭包)
  3. brew 安装软件能指定文件夹吗_Mac下Homebrew安装的软件放在什么地方
  4. 检察日报:需从预防犯罪视角对私人数字货币实施刑法规制
  5. 10、32位 x86处理器编程架构
  6. python修改txt里面的内容_python修改txt部分内容,并保存。
  7. javascript语言
  8. 微信公众号爬虫方案分析
  9. 清华大学中文语音识别数据 THCHS30
  10. 如何利用Pix2Pix将黑白图片自动变成彩色图片
  11. 南邮物联网学院计算机考研,研友分享南京邮电大学物联网学院两个专业的一点看法...
  12. Python3-爬虫~selenium\phantomjs\爬取XX网页电影过程中向下滚动网页问题
  13. 腾讯会议录制视频下载
  14. linux平台MSG_OOB选项测试
  15. pptpd 安装步骤
  16. 声学模型训练----Acoustic Modeling
  17. Django开源项目
  18. SQL--打折日期交叉问题
  19. 光端机连接示意图详细连接方式图解
  20. IDEA Diagrams使用实现类图(类关系图、子类、父类)

热门文章

  1. linux镜像文件超过4G怎么办,Systemback无法将超过4G的sblive文件转存为镜像文件的解决办法...
  2. Linux-文件打开数配置实践
  3. python程序文件默认扩展名_Python程序文件的扩展名是:
  4. 12.分布式定时任务(xxl-job)
  5. content-box和boder-box的区别
  6. 汽车软件行业工程师详细介绍?(上)
  7. github协同工作流程(一)
  8. 复杂网络——活跃度驱动模型(activity-driven model)原理及算法实现
  9. 两种双绞线的线序568A与568B
  10. FPGA LVDS液晶屏