折腾Java设计模式之解释器模
解释器模式
解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。
意图 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
主要解决 对于一些固定文法构建一个解释句子的解释器。
何时使用 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
如何解决 构件语法树,定义终结符与非终结符。
关键代码 构件环境类,包含解释器之外的一些全局信息,一般是 HashMap。
解释器模式相关UML图
类图
![]()

可以看出右侧的协作图(object collaboration diagram)展现出运行时的解释器模式。Client向右侧抽象语法树发送解释请求,请求被转发并向下到树结构的所有对象。
解释器模式的主要角色
抽象解释器(AbstractExpression/Expression):声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作。具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器NonterminalExpression完成。
终结符表达式(TerminalExpression):实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。终结符一半是文法中的运算单元,比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
非终结符表达式(NonterminalExpression):文法中的每条规则对应于一个非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,+就是非终结符,解析+的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
环境角色(Context):这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。
干货代码
简单的一个解释器计算加减乘除算法,环境上下文没有用好,其实计算规则更多的是人为设定的了。
本次的抽象接收器用的是抽象类,用接口代替也可以。
//抽象解释器
public abstract class AbstractExpression {
public abstract int interpreter(Context context);
}
//非终结表达式:加法
@Data
@AllArgsConstructor
public class Add extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
@Override
public int interpreter(Context context) {
return left.interpreter(context) + right.interpreter(context);
}
}
//非终结表达式:减法
@Data
@AllArgsConstructor
public class Subtract extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
@Override
public int interpreter(Context context) {
return left.interpreter(context) - right.interpreter(context);
}
}
//非终结表达式:乘法
@Data
@AllArgsConstructor
public class Multiply extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
@Override
public int interpreter(Context context) {
return left.interpreter(context) * right.interpreter(context);
}
}
//非终结表达式:除法
@Data
@AllArgsConstructor
public class Division extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
@Override
public int interpreter(Context context) {
int right = this.right.interpreter(context);
if (right != 0) {
return left.interpreter(context) / right;
}
return -1;
}
}
//终结表达式:变量
@Data
@AllArgsConstructor
public class Variable extends AbstractExpression {
private final String key;
@Override
public int interpreter(Context context) {
return context.getValue(key);
}
}
//环境上下文
@Getter
public class Context {
private final Map<String, Integer> valueMap = Maps.newHashMap();
public void addValue(final String key, final int value) {
valueMap.put(key, Integer.valueOf(value));
}
public int getValue(final String key) {
return valueMap.get(key).intValue();
}
}
//
public class Application {
public static void main(String[] args) {
Context context = new Context();
context.addValue("a", 6);
context.addValue("b", 9);
context.addValue("c", 1);
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
AbstractExpression multiplyValue = new Multiply(a, b);
AbstractExpression subtractValue = new Subtract(a, b);
AbstractExpression addValue = new Add(subtractValue, c);
AbstractExpression divisionValue = new Division(multiplyValue, addValue);
log.info("{}", context.getValueMap());
log.info("(a*b)/(a-b+c) = {}", divisionValue.interpreter(context));
}
}
结果如下:

Java中的应用
java中的表达式引擎
Java表达式引擎fel/groovy/expression4j/java脚本引擎的性能对比
JDK中的应用
这个模式通常定义了一个语言的语法,然后解析相应语法的语句。
java.util.Pattern
java.text.Normalizer
java.text.Format
参考
折腾Java设计模式之解释器模的更多相关文章
- 折腾Java设计模式之解释器模式
解释器模式 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 意图 给定一个语言,定义它的文法表 ...
- 折腾Java设计模式之单例模式
博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...
- 折腾Java设计模式之建造者模式
博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...
- 折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...
- 折腾Java设计模式之备忘录模式
原文地址:折腾Java设计模式之备忘录模式 备忘录模式 Without violating encapsulation, capture and externalize an object's int ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 折腾Java设计模式之模板方法模式
博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...
- 折腾Java设计模式之访问者模式
博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...
- 折腾Java设计模式之命令模式
博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...
随机推荐
- RabbitMQ消息队列系列教程(二)Windows下安装和部署RabbitMQ
摘要 本篇经验将和大家介绍Windows下安装和部署RabbitMQ消息队列服务器,希望对大家的工作和学习有所帮助! 目录 一.Erlang语言环境的搭建 二.RabbitMQ服务环境的搭建 三.Ra ...
- 浅析HSTS
浅析HSTS 一.HSTS是什么? HSTS全称:HTTP Strict Transport Security,意译:HTTP严格传输安全,是一个Web安全策略机制. 二.HSTS解决什么问题? 它解 ...
- springboot加ES实现全局检索
ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...
- PHP实现用户注册并保存数据到文件
首先我们实现功能时,分析实现的步骤是什么,就这个而言,我们应该接收用户提交的数据并进行校验,然后保存在文件,最后给用户反馈. 这里需要注意的是为了避免嵌套过深,这里使用自定义函数来实现,其代码如下: ...
- 如何解决http请求返回结果中文乱码
如何解决http请求返回结果中文乱码 1.问题描述 http请求中,请求的结果集中包含中文,最终以乱码展示. 2.问题的本质 乱码的本质是服务端返回的字符集编码与客户端的编码方式不一致. 场景的如服务 ...
- 北上广等一线城市IT岗位已接近饱和?
IT行业的技术者,时常被我们戏称为「IT民工」,虽然行业内巨大的人才需求和相对容易得到的高薪在源源不断的吸引各路人马加入,但它依旧在全球最缺人的十大行业中位居榜首. 我身边的朋友大都问过我这样一个疑问 ...
- tensorflow、cuda、cudnn之间的版本对应关系
原文链接 tensorflow-gpu v1.9.0 | cuda9.0 | cuDNN7.1.4可行 | 备注:7.0.4/ 7.0.5/ 7.1.2不明确 tensorflow-gpu v1. ...
- Docker 下载镜像
文章首发个人网站: https://www.exception.site/docker/docker-pull-image 本文中,我们将需要学习 Docker 如何下载镜像? 一.前言 大家都知道, ...
- qt 拖拽 修改大小(二)
最近项目需要实现windows下橡皮筋的效果,所以对此做了一些了解,特此记录. 首先windows系统是支持橡皮筋效果的,需要使用win32方 法:SystemParametersInfo(SPI_S ...
- phpStrom映射代码