如何让孩子爱上设计模式 ——20.解释器模式(Interpret
标签: 设计模式初涉
描述性文字
解释器模式是一个用的比较少的设计模式,而且不太好理解,先说下概念相关的东西
再写个代码示例帮助下理解:
定义
给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个
解释器,客户端可以使用这个解释器来解释这个语言中的句子。
四个角色
-
AbstractExpression:抽象表达式,声明一个所有具体表达式都要实现的接口,
接口中主要是一个interpret()方法,称为解释操作,具体的解释任务由他的各个实现
类来完成,而具体的解释器又分别由 终结符解释器 与 非终结符解释器 完成。 -
TerminalExpression:终结符表达式,实现与文法中的元素相关联的解释操作,
通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。、
终结符一半是文法中的运算单元,比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,
对应的解析R1和R2的解释器就是终结符表达式。 -
NonterminalExpression :非终结符表达式,文法中的每条规则对应于一个非终
结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,
+就是非终结符,解析+的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂
程度而增加,原则上每个文法规则都对应一个非终结符表达式。 -
Context:上下文环境,存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们
给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充
当环境角色就足够了。
UML类图
![](http://static.zybuluo.com/coder-pig/hlv67hov2kyzqkmb2kopl1nu/image_1bbkrlahurjp1uneiom133s182t9.png)
优缺点
优点
- 1.易于实现简易语法,一条语法规则用一个解释器对象解释执行
- 2.易于扩展新的语法,只需创建相应的解释器对象,在创建抽象语法树的时候使用即可。
- 3.增加了新的解释表达式的方式
缺点
- 1.可使用场景较少
- 2.对于复杂的文法比较难维护
- 3.引起类膨胀
- 4.采用递归调用方法,效率,性能,维护问题
使用场景
- 1.重复发生的问题
- 2.一个简单语法需要解释的场景
- 3.将一个解释执行的语言中的句子表示为一个抽象语法树
代码示例
定义一个能够解释加减法的解释器作为示例
先定义抽象表达式
![](http://static.zybuluo.com/coder-pig/6q0420yqf8kj6k836niiov8v/image_1bbksku8r1snuk3nnvsf3bkj2m.png)
接着定义加减法两个非终结符表达式
![](http://static.zybuluo.com/coder-pig/xgoci9bb2hx4y8sj1bjh1fhs/image_1bbksmgmh10pbppn11to1fbl12ss13.png)
![](http://static.zybuluo.com/coder-pig/2frhzexyc28dh8ybuq82rji1/image_1bbksn2d01b1c60c1j45131h1mqh1g.png)
再接着定义常量与变量两个终结符表达式
![](http://static.zybuluo.com/coder-pig/j1jvi65g2kihbajjo8r6123t/image_1bbkso9r9dio1j7hinf1h8kepl1t.png)
![](http://static.zybuluo.com/coder-pig/aslq0moofv1riuefk7zx1kvg/image_1bbksov9o2ep1dr21o9udc516ou2a.png)
然后定义上下文环境,用Map存放各个终结符对应的具体值
![](http://static.zybuluo.com/coder-pig/xqzohatwhacoekzsjbkxird2/image_1bbksqpik1lfhev51mtg15gp1lsr2n.png)
最后客户端调用
![](http://static.zybuluo.com/coder-pig/9ey7qtb98kmtp3vnrhb6l9m6/image_1bbkssd5bpoj151q1rtk19kco4734.png)
输出结果
![](http://static.zybuluo.com/coder-pig/vknr60lqs6ufpdb5fohvazws/image_1bbksspqu1msk848pmp141gtqp3h.png)
可能看到输出结果的你还是一脸懵逼,到底解释器模式做了些什么?
答:定义了一套简单语法,每个终结符都有一个对应的值存起来了,
然后当你输了一串终结符,最后解释能得出一个正确结果。
本节示例代码:
https://github.com/coder-pig/DesignPatternsExample/tree/master/19.Interpreter%20Pattern