github地址:https://github.com/1711680493

点我进入github

如需了解更多设计模式,请进入我的设计模式专栏

解释器模式

提供如何定义语言的文法,以及对语言句子的解释方法

文法指语言的语法规则,而句子是语言集中的元素

正则表达式等都是解释器模式

解释器模式是一种行为型模式

优点

扩展性好,由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法
容易实现,在语法树种的每个表达式节点类都是相似的,所以实现其文法较为容易

缺点

执行效率较低,解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,

且代码的调试过程也比较麻烦
会引起类膨胀,解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,

类的个数将急剧增加,导致系统难以管理与维护
可应用的场景比较少,在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很难被用到

解释器模式的结构与组合模式相似,不过其包含的组成元素比组合模式多,
而且组合模式是对象结构型模式,而解释器模式是类行为型模式

结构

抽象表达式角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法interpret()
终结符表达式角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,

文法中的每一个终结符都有一个具体终结表达式与之相对应
非终结者表达式角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,

文法中的每条规则都对应于一个非终结者表达式
环境角色:通常包含各个解释器需要的数据或是公共的功能,一般来传递所有解释器共享的数据,
    后面的解释器可以从这里获取这些值
客户端:主要任务是需要将分析的句子或表达式转换成使用解释器对象描述的抽象语法树,
    然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法

例子

我们通过此模式来解释一个加法

/*** 解释器模式* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
public class InterpreterMode {public static void main(String[] args) {//创建环境Context context = new Context();//执行一段表达式context.exec("1 + 1");context.exec("2+1");context.exec("1024+ 2048");context.exec("1024 +1024");}
}/*** 抽象表达式* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
interface Interpreter {/*** 表达式执行完后返回的值* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @param interpreter 表达式* @return*/int exec(String interpreter);
}/*** 加数 终结者* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
class AddInterpreter implements Interpreter {@Overridepublic int exec(String interpreter) {//根据+分割 这里的\\是转义String[] strs = interpreter.split("\\+");if (strs.length > 1) {//去空格 转 int 返回return Integer.parseInt(strs[0].trim());}return 0;}}
/*** 被加数 终结者* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
class UnAddInterpreter implements Interpreter {@Overridepublic int exec(String interpreter) {//根据+分割String[] strs = interpreter.split("\\+");if (strs.length > 1) {//去空格 转 int 返回return Integer.parseInt(strs[1].trim());}return 0;}}/*** 运算符 终结者* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
class SymbolInterpreter implements Interpreter {@Overridepublic int exec(String interpreter) {//运算符有很多,这里不区分加减乘除... 我们定义//返回0则为+,1为-,2为*,3为/if (interpreter.indexOf('+') != -1) {return 0;} else if (interpreter.indexOf('-') != -1) {return 1;} else if (interpreter.indexOf('*') != -1) {return 2;} else {return 3;}}}/*** 加法非终结者表达式 调用其他终结者表达式完成任务* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
class AddNoInterpreter implements Interpreter {private AddInterpreter add;private SymbolInterpreter symbol;private UnAddInterpreter unAdd;public AddNoInterpreter(AddInterpreter add,SymbolInterpreter symbol,UnAddInterpreter unAdd) {this.add = add;this.symbol = symbol;this.unAdd = unAdd;}@Overridepublic int exec(String interpreter) {//判断符号是否为加号 是则解析加数和被加数 并执行操作return symbol.exec(interpreter) == 0 ? add.exec(interpreter) + unAdd.exec(interpreter) : 0;}}/*** 环境类* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>* @version 1.0*/
class Context {//持有非终结者引用private AddNoInterpreter ANI;public Context() {//初始化ANI = new AddNoInterpreter(new AddInterpreter(), new SymbolInterpreter(), new UnAddInterpreter());}/*** 执行操作* @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a>*/public void exec(String add) {System.out.println(add + '=' + ANI.exec(add));}
}

应用场景

当语言的文法较为简单,且执行效率不是关键问题时
当问题重复出现,且可以用一种简单地语言来进行表达时
当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象的语法树的时候,如XML文档解释

注意:解释器模式在实际的软件开发中使用比较少,因为会引起效率性能维护等问题,

在Java中可以用Expression4J或Jep来设计

扩展

在Java中,如果要对数表达式进行分析与计算,无须再用解释器模式进行设计了,Java提供了强大的数学公式解析器Expression4J,MESP,Jep等...

总结

思想:解释器模式就是用于解释一些东西

使用:根据模式结构,大致分工 (

客户端调用环境,环境持有非终结者并调用,非终结者持有 终结者/非终结者 并调用执行解释操作

)

[设计模式]解释器模式相关推荐

  1. Python设计模式-解释器模式

    Python设计模式-解释器模式 代码基于3.5.2,代码如下; #coding:utf-8 #解释器模式class PlayContext():play_text = Noneclass Expre ...

  2. 设计模式 | 解释器模式及典型应用

    微信原文:设计模式 | 解释器模式及典型应用 博客原文:设计模式 | 解释器模式及典型应用 本文主要介绍解释器模式,在日常开发中,解释器模式的使用频率比较低 解释器模式 解释器模式(Interpret ...

  3. 解释器android,Android的设计模式-解释器模式

    前言 Android的设计模式系列文章介绍,欢迎关注,持续更新中: 1.定义 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子. 2.介绍 解释器模式属于行 ...

  4. C++设计模式-解释器模式

    目录 基本概念 代码与实例 基本概念 解释器模式(interpreter):给定一个语言,定义他的文法的一种表示,并定义一个解释器,这个解释器应该使用该表示来解释语言中的句子. 如果一种特定类型的问题 ...

  5. 深入浅出设计模式——解释器模式(Interpreter Pattern)

    模式动机 如果在系统中某一特定类型的问题发生的频率很高,此时可以考虑将这些问题的实例表述为一个语言中的句子,因此可以构建一个解释器,该解释器通过解释这些句子来解决这些问题. 解释器模式描述了如何构成一 ...

  6. PHP设计模式——解释器模式

    声明:本系列博客参考资料<大话设计模式>,作者程杰. 解释器模式:Given a language, define arepresentation for its grammar alon ...

  7. 初识设计模式 - 解释器模式

    简介 在某些情况下,为了更好地描述某一些特定类型的问题,我们可以创建一种新的语言,这种语言拥有自己的表达式和结构,即文法规则. 解释器设计模式(Interpreter Design Pattern)描 ...

  8. C++设计模式——解释器模式(interpreter pattern)

    一.原理讲解 1.1意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 1.2应用场景 文法简单.对于复杂的文法,文法的类层次变得庞大而无法管理:此 ...

  9. Java设计模式--解释器模式

    解释器模式 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. Interpreter Pattern Given a language, define ...

  10. 设计模式——解释器模式

    名称 Interpreter 结构   意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 适用性 当有  1// Interpreter  2   ...

最新文章

  1. linux硬盘写0,linux – kworker消耗90%的IO和零磁盘写入
  2. spyder 断点调试python代码
  3. Win32系统下安装Win64补充说明
  4. N皇后问题的两个最高效的算法
  5. ARM和NEON指令 very gooooooood.............
  6. caffeine 4hash lfu频度记录
  7. 数组的foreach方法和jQuery中的each方法
  8. es分页查询重复数据_ES优化 - 巨量数据如何提高查询性能
  9. python去除行末符EOL的一般方法
  10. centos7改语言包
  11. MineCraft note
  12. win、linux下tomcat内存的修改
  13. Linux3.2.8系统启动过程及启动延时初步分析
  14. .net连接SqlServer数据库
  15. 微信小程序模拟器加载图片成功,真机加载失败
  16. Linux中有play命令吗,linux play命令
  17. 解决Windows server 2003不认U盘
  18. Xilinx FPGA资源解析与使用系列——Transceiver(一)参考时钟解析
  19. EasyExcel合并单元格策略样例
  20. scala2.11.8安装

热门文章

  1. 4999以内阿拉伯数字转罗马字符
  2. 51单片机c语言脉冲计数实验报告,单片机计数器实验报告.doc
  3. (十一)【数电】(组合逻辑电路)数据分配器和数据选择器
  4. Android手机型号及产品名
  5. mtr 检测网络 查看服务器网络是否丢包
  6. apply update from ADB
  7. 饥荒显示服务器建立时遇到问题,饥荒联机版建立服务器出现问题怎么回事 | 手游网游页游攻略大全...
  8. 针对初学者的 MQL 5 中的自定义指标
  9. 华硕B85M-D台式机主板音响没反应,更新驱动还是找不到realtek高清晰音频管理器原因及解决方案
  10. Windows控制面板没有Realtek高清晰音频管理器