前言

解释器模式是一种使用较少的行为型模式;
提供了一种解释语言的语法或表达式的方式,通过该接口解释一个特定的上下文。

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

使用场景:

  • 如果某个简单的语言需要解释执行而且可以将该语言中的语句表示为一个抽象语法树时,可以考虑使用解释器模式。
    如一个简单的含有加减运算的数学表达式:p+q+m-n,像这样的表达式其构成无非就两种,一种是以pqmn这类的具体参数表示的符号,其无法再被推导,我们称为终结符号;另一种则是以“+”和“-”构成的算术运算符,在该运算法的两边总能找到有意义的具体计算参数,我们称其为非终结符号;

  • 在某些特定的领域出现不断重复的问题时,可以将该领域的问题转化为一种语法规则下的语句,然后构建解释器来解释该语句;

UML类图:

  • AbstractExpression:抽象表达式;
    声明一个抽象的解释操作父类,并定义一个抽象的解释方法,其具体的实现在各个具体的子类解释器中完成;
  • TerminalExpression:终结符表达式;
    实现文法中与终结符有关的解释操作。文法中每一个终结符都有一个具体的终结表达式与之对应。
  • NonterminalExpression:非终结符表达式;
    实现文法中与非终结符有关的解释操作;
  • Context:上下文环境类;
    包含解释器之外的全局信息;
  • Client:客户类;
    解析表达式,构建抽象语法树,执行具体的解释操作等;

实现示例

这里我们以对算法表达式的解释举例,如表达式m+n+p,我们使用解释器对该表达式进行解释,那么代表数字的mnp三个字母可以看成终结符号,而+这个算术运算符号可以当做非终结符号。

  • 定义抽象解释器表示数学运算,ArithmeticExpression
/*** 抽象表达式*/
abstract class ArithmeticExpression {/*** 抽象的解析方法* @return 解析得到具体的值*/abstract fun interpret(): Int
}
  • 定义数字解析器,NumExpression
/*** 数字解析器*/
class NumExpression(private val num: Int) : ArithmeticExpression() {override fun interpret(): Int {return num //直接返回对应数字}
}
  • 定义运算符号抽象解释器,OperatorExpression
/*** 运算符号抽象解释器 为所有运算符号解释器共性的提取* @param exp1 exp2 声明两个成员变量存储运算符号两边的数字解释器*/
abstract class OperatorExpression(private val exp1: ArithmeticExpression,private val exp2: ArithmeticExpression
) : ArithmeticExpression() {}
  • 定义加法运算抽象解释器,AdditionExpression
/*** 加法运算抽象解释器*/
class AdditionExpression(private val exp1: ArithmeticExpression,private val exp2: ArithmeticExpression
) : OperatorExpression(exp1, exp2) {override fun interpret(): Int {return exp1.interpret() + exp2.interpret()}
}
  • 测试类,进行验证;
object Test {@JvmStaticfun main(args: Array<String>) {println("计算结果为:" + calculator("1 + 2 + 3 + 5"))}/*** 用于存储并操作所有相关的解释器*/private val stackExpression = Stack<ArithmeticExpression>()private fun calculator(expression: String): Int {var exp1: ArithmeticExpressionvar exp2: ArithmeticExpression//假设这里表达式字符以空格进行分割val splits: List<String> = expression.split(" ")for (i in splits.indices) {if (splits[i] == "+") {//当前是+号,则将栈中的解释器取出来作为运算符号左边的解释器exp1 = stackExpression.pop()//下一个坐标数据作为运算符号右边的解释器exp2 = NumExpression(splits[i + 1].toInt())//构造加法运算解释器存放到栈中stackExpression.push(AdditionExpression(exp1, exp2))} else {if (i > 0 && splits[i - 1] == "+") {//上面+号后面的数据已经存放到AdditionExpression中continue}stackExpression.push(NumExpression(splits[i].toInt()))}}return stackExpression.pop().interpret()}
}

当我们想定义减法操作时,只需要继承OperatorExpression类进行扩展即可;

Android源码中的解释器模式

  • 解析AndroidManifest.xmlPackageParser类;

总结

优点:
灵活的扩展性,当我们想对文法规则进行扩展延伸时,只需要增加对应的非终结符解释器,并在构建抽象语法树时,使用到新增的解释器对象进行具体的解释即可;

缺点:
对于每一条文法都需要对应至少一个解释器,会生成大量的类,不利于后期维护,因此,对于过于复杂的文法不推荐使用解释器模式;

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

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

  1. Android设计模式详解之建造者模式

    前言 Builder模式是一种创建型设计模式. 定义:将一个复杂对象的创建与它的表示分离,使得同样的构造过程可以创建不同的表示. 使用场景: 相同的方法,不同的执行顺序,产生不同的事件结果时: 多个部 ...

  2. Android设计模式详解之备忘录模式

    前言 备忘录模式是一种行为模式,该模式用于保存对象当前状态,并且在之后可以再次恢复到此状态: 定义:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样,以后就可以将该对象恢 ...

  3. Android设计模式详解之责任链模式

    前言 责任链模式是行为型设计模式: 定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 使用场景: 多 ...

  4. Android设计模式详解之观察者模式

    前言 观察者常用于订阅-发布系统,能够将观察者和被观察者进行解耦,降低两者之间的依赖: 定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并被自动更新. ...

  5. C++设计模式详解之外观模式解析

    C++ 外观模式 外观模式定义 外观模式提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用. 个人理解:外观模式,实际就是添加一层封装 比较简单 外观模式实例 ...

  6. C++设计模式详解之模板模式解析

    C++ 模板方法模式解析 模板方法模式定义 模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现 模板方法模式实例 以考试为例,考数学和考语文的过程几乎都是一样的,就是准备考试,背书,写试 ...

  7. C++设计模式详解之命令模式解析

    C++ 命令模式定义 命令模式将请求封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象. 个人理解: 命令模式,其实实质上就是去耦合的操作,让各个部分尽可能的关联性降低,以便修改或增加某些功 ...

  8. C++设计模式详解之工厂模式解析

    C++ 工厂方法模式解析 工厂方法模式原则 让子类决定该创建的对象是什么,来达到将对象创建的过程.封装了对象创建的过程.实现了封装的目的.主要就是创建者类和产品类,让创建者自动绑定产品. 工厂方法模式 ...

  9. 设计模式详解:建造者模式

    今天来看一下创建新模式中的第五种模式:建造者模式.仍然是先看两张图,复习模式类型,加深记忆. 定义: 建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. Build ...

最新文章

  1. sm2加密算法实例_实例说明加密算法
  2. 北邮计算机科学技术是学硕吗,【计算机考研】2020北京邮电大学计算机科学与技术考研初试科目、参考书目、复试详情汇总...
  3. 物理哲学和生物哲学的对抗
  4. OpenGL 分层渲染Layered Rendering的实例
  5. CSS 单行溢出文本显示省略号...的方法(兼容IE FF)(转)
  6. C++ 在派生类中使用using声明改变基类成员的可访问性
  7. linux 内网怎么安装git环境_linux 安装go环境
  8. python去掉html标签_python 去除html标签的几种方法
  9. macos server 恢复安装_如何通过 macOS 恢复功能重新安装 macOS
  10. oralcle中的性能统计基本用法statpack
  11. 通俗易懂!视觉slam第九部分——光流(Optical Flow)
  12. Gitl用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner 解释
  13. 【转载】Unity3D导入FBX模型的相关属性介绍
  14. C# 操作word之在表格中插入新行、删除指定行
  15. 申论公文题-评论类-1
  16. 迷失逃脱小程序_恐怖游戏大全:奇幻夜之迷失!密室逃脱解谜恐怖小程序
  17. POI Excel设置列宽
  18. 【FastJson】使用FastJson将Json数组转换成字符串
  19. 九十年前到江西(2009-06-09)
  20. 关于64位windows7系统下安装IE11失败(9c59)的解决过程记录

热门文章

  1. linux menuconfig搜索,Linux make menuconfig查找并快速跳转指定驱动选项
  2. Kali 安装无线网卡驱动
  3. mysql中sql中统计结果四舍五入保留两位小数
  4. 服务器操作系统加固软件,服务器操作系统安全加固软件
  5. cocos creator 打包原生安卓apk 构建与编译
  6. 【爬虫】Scrapy爬取古风漫画网
  7. 2021.1.21——星露谷作物计算器的可视化
  8. java水平线代码_java 绘制直线,跪求源代码???
  9. Ubuntu常用工具安装方法及地址
  10. 私企做阿米巴经营模式失败的原因——灵魂5问!