设计模式-解释器模式
背景
随着中国加入wto各国贸易频繁,不同的国度使用的语言不一样,但是在交流过程中很多国家以英文作为交流的对象,而翻译官就是将将两种不同的语言互相翻译,传达各自听得懂的语言,这里翻译,可以通过解释器模式一样来转换。
解释器模式是什么?
解释器模式(Interpreter Pattern),属于行为模式,给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
解释器模式可以干嘛?
通过解释器模式,可以给特定的字符定义解释的语言,通过解释后的语言进行解释成最终想要的结果。对于一些固定的语法沟通成一个解释的句子的解释器,比如 + - * / = 这种计算中常用到的。
优点:
易拓展:容易拓展各类角色,并且比较灵活增减;
缺点:
效率低:需要通过解析成最终文本,所以计算量较大,效率比较低;
维护成本高:对于复杂的文法维护成本相当高;
角色:
抽象解释器(AbstractExpression/Expression):抽象表达式。声明一个抽象的解释操作,该接口为抽象语法树中所有的节点共享。
终结符表达式(TerminalExpression):终结符表达式。实现与文法中的终结符相关的解释操作。实现抽象表达式中所要求的方法。文法中每一个终结符都有一个具体的终结表达式与之相对应。
非终结符表达式(NonterminalExpression):非终结符表达式。为文法中的非终结符相关的解释操作。
环境角色(Context):环境类。包含解释器之外一些全局信息。
个人理解:
解释器就比如像讲的粤语转成普通话,而这个转换器就似于解释器,其中里面涉及语法和发音就是文本,具体的转就是语法问题;
解释器模式类图
源码下载:https://gitee.com/hong99/design-model/issues/I1IMES
实现代码
/**
* @Auther: csh
* @Date: 2020/6/8 11:42
* @Description:抽象解释器
*/
public interface Expression {
/**
*
* 功能描述:解释器接口
*
* @param:
* @return:
* @auther: csh
* @date: 2020/6/8 11:55
*/
public String interpret();
}
/**
* @Auther: csh
* @Date: 2020/6/8 14:22
* @Description:终结符表达式
*/
public class TerminalExpression implements Expression {
private String context;
public TerminalExpression(String context) {
this.context = context;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
@Override
public String interpret() {
return context;
}
}
/**
* @Auther: csh
* @Date: 2020/6/8 11:56
* @Description:非终结符表达式
*/
public class ChineseExpression implements Expression {
private Expression expression;
public ChineseExpression(Expression expression) {
this.expression = expression;
}
@Override
public String interpret() {
String interpret = expression.interpret();
if(interpret.contains("chinese")){
return "中文";
}
return null;
}
}
/**
* @Auther: csh
* @Date: 2020/6/8 14:12
* @Description:非终结符表达式
*/
public class EnglishExpression implements Expression {
private Expression expression;
public EnglishExpression(Expression expression) {
this.expression = expression;
}
@Override
public String interpret() {
String interpret = expression.interpret();
if(interpret.contains("english")){
return "英文";
}
return null;
}
}
/**
* @Auther: csh
* @Date: 2020/6/8 15:01
* @Description:解释器工具
*/
public class LanguageUtil{
private Expression expression;
public LanguageUtil(Expression expression) {
this.expression = expression;
}
public String out(){
return expression.interpret()==null?"无法解释":expression.interpret();
}
}
/**
* @Auther: csh
* @Date: 2020/6/8 14:42
* @Description:
*/
public class Client {
public static void main(String[] args) {
String chinese = "chinese";
String test = "test";
String english = "english";
Expression chineseExpression = new TerminalExpression(chinese);
Expression englishExpression = new TerminalExpression(english);
Expression testExpression = new TerminalExpression(test);
System.out.println(new LanguageUtil(new EnglishExpression(englishExpression)).out());
System.out.println(new LanguageUtil(new ChineseExpression(chineseExpression)).out());
System.out.println(new LanguageUtil(new EnglishExpression(testExpression)).out());
}
}
英文
中文
无法解释
源码下载:https://gitee.com/hong99/design-model/issues/I1IMES最后
解释器模式说实用处不多,而且简单可以非常简单,复杂可以非常复杂,每个人的理解和写法不同,并且找了相关的资料基本每个人都有每个人的理解,但最终呈现出来的结果都不一样。不过本质是一样的无法就是将对象或者文本转通过特定语法转换成你想要的结果,也就是根据你自己定义的规则转换,所以变化多端。当然看了下网上各种大神的文案和分析,发现这个模式在spring el里面用得还是比较好的,还有我们常用的正则表达式基本都是这种模式来呈现的。
用到解释器的框架或场景
java中的表达式引擎
parsii
JEval
JEPLite
expr
Janino
MathEval
Java表达式引擎fel/groovy/expression4j/java脚本引擎的性能对比
JDK中的应用
java.util.Pattern
java.text.Normalizer
java.text.Format
- 计算机视觉任务:图像梯度和图像完成
- Yarn【label-based scheduling】实战总结(一)
- 配置sonarqube+maven
- Yarn【label-based scheduling】实战总结(二)
- HDFS学习:HDFS机架感知与副本放置策略
- spring cloud 报错Error creating bean with name 'hystrixCommandAspect' ,解决方案
- Spring Security OAuth2 Demo
- SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存
- 线性回归与最小二乘法 | 机器学习笔记
- 添加sqljdbc4的maven依赖
- MyBatis 实现关联表查询
- 数据结构 | 栈
- mybatis 针对SQL Server 的 主键id生成策略
- 算法 | 排序算法图形化比较:快速排序、插入排序、选择排序、冒泡排序
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Python 基础(十六):迭代器与生成器
- MySQL information_schema详解 COLUMNS
- MySQL information_schema详解 COLUMN_PRIVILEGES
- 一分钟学Python|Python的字典
- MySQL information_schema详解 ENGINES
- 一日一技:不用轮询,基于事件监控文件变动
- Python 基础(十七):装饰器
- XtraBackup工具详解 Part 10 使用innobackupex对数据库进行部分备份(指定表或数据库)
- Python 基础(十九):数学相关模块
- XtraBackup工具详解 Part 11 使用innobackupex对部分备份进行恢复
- XtraBackup工具详解 Part 12 流式和压缩备份
- 基于STM32+RT-Thread的新冠肺炎疫情监控平台
- Python 基础(二十):sys 模块
- [Oracle 故障处理]记一次Windows监听启动失败
- Python 基础(二十一):argparse 模块