本文源码:GitHub·点这里 || GitEE·点这里

一、解释器模式

1、基础概念

解释器模式是对象的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的表达式。

2、模式图解

3、核心角色

(1)、抽象表达式

Express:声明具体表达式角色需要实现的抽象接口,该接口主要提供一个interpret()方法,称做解释操作。

(2)、终结符表达式

TerminalExpress:实现抽象表达式角色接口,主要是一个interpret()方法;每个终结符都有一个具体终结表达式与之相对应。比如解析c=a+b,a和b是终结符,解析a和b的解释器就是终结符表达式。

(3)、非终结符表达式

NotTerminalExpress:每一条规则都需要一个具体的非终结符表达式用来衔接,一般是指运算符或者逻辑判断,比如c=a+b,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。

(4)、环境容器

DataMap:一般是用来存放各个终结符所对应的具体值,比如c=a+b转换为c=1+2。这些信息需要一个存放环境。

4、源代码实现

  • 类图结构

  • 源码实现
public class C01_InScene {
public static void main(String[] args) {
DataMap dataMap = new DataMap();
TerminalExpress terminalExpress1 = new TerminalExpress("num1");
TerminalExpress terminalExpress2 = new TerminalExpress("num2");
TerminalExpress terminalExpress3 = new TerminalExpress("num3");
dataMap.putData(terminalExpress1, 1);
dataMap.putData(terminalExpress2, 2);
dataMap.putData(terminalExpress3, 3);
// 1+2-3 = 0
System.out.println(new Minus(
new Add(terminalExpress1,terminalExpress2), terminalExpress3)
.interpret(dataMap));
}
}
// 解释器接口
interface Express {
Integer interpret(DataMap dataMap) ;
}
// 非终结符表达式
abstract class NotTerminalExpress implements Express {
Express express1,express2;
public NotTerminalExpress(Express express1, Express express2){
this.express1 = express1;
this.express2 = express2;
}
}
// 终结符表达式: 1+2 终结符: 1 和 2
class TerminalExpress implements Express {
public String field ;
public TerminalExpress (String field){
this.field = field ;
}
@Override
public Integer interpret(DataMap dataMap) {
return dataMap.getData(this);
}
}
// 加法表达式
class Add extends NotTerminalExpress {
public Add (Express e1, Express e2) {
super(e1, e2);
}
// 将两个表达式相减
@Override
public Integer interpret(DataMap context) {
return this.express1.interpret(context) + this.express2.interpret(context);
}
}
// 减法表达式
class Minus extends NotTerminalExpress {
public Minus (Express e1, Express e2) {
super(e1, e2);
}
// 将两个表达式相减
@Override
public Integer interpret(DataMap context) {
return this.express1.interpret(context) - this.express2.interpret(context);
}
}
// 数据容器
class DataMap {
private Map<Express,Integer> dataMap = new HashMap<>() ;
public void putData (Express key,Integer value){
dataMap.put(key,value) ;
}
public Integer getData (Express key){
return dataMap.get(key) ;
}
}

二、Spring框架应用

1、源码案例

import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class SpringTest {
public static void main(String[] args) {
SpelExpressionParser parser = new SpelExpressionParser () ;
Expression expression = parser.parseExpression("(1+3-2)*3") ;
Integer result = (Integer)expression.getValue() ;
System.out.println("result="+result);
}
}

2、代码分析

(1)Expression结构

表达式接口:具有不同的实现类。

interface Expression
class CompositeStringExpression implements Expression
class LiteralExpression implements Expression
class SpelExpression implements Expression

核心方法:

Object getValue() throws EvaluationException;

(2)SpelExpressionParser结构

SpelExpressionParser extends TemplateAwareExpressionParser
TemplateAwareExpressionParser implements ExpressionParser
interface ExpressionParser

(3)ExpressionParser接口

public interface ExpressionParser {
Expression parseExpression(String var1) ;
Expression parseExpression(String var1, ParserContext var2) ;
}

(4)Expression获取

根据不同的条件获取不同的Expression对象。这里产生类的依赖关系。

源码位置:TemplateAwareExpressionParser

public Expression parseExpression(String expressionString,
ParserContext context)
throws ParseException {
if (context == null) {
context = NON_TEMPLATE_PARSER_CONTEXT;
}
return context.isTemplate() ?
this.parseTemplate(expressionString, context) :
this.doParseExpression(expressionString, context);
}

三、模式总结

  • 场景

编译器、运算符表达式、正则表达式、机器人等。

  • 优点

当有一个表达式或者语言需要解释执行,该场景下的内容可以考虑使用解释器模式,使程序具有良好的扩展性。

  • 缺点

解释器模式会引起类膨胀,会导致程序执行和调试非常复杂,不容易理解。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

Java描述设计模式(14):解释器模式的更多相关文章

  1. 折腾Java设计模式之解释器模式

    解释器模式 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 意图 给定一个语言,定义它的文法表 ...

  2. 北风设计模式课程---解释器模式(Interpreter Pattern)

    北风设计模式课程---解释器模式(Interpreter Pattern) 一.总结 一句话总结: 不仅要通过视频学,还要看别的博客里面的介绍,搜讲解,搜作用,搜实例 设计模式都是对生活的抽象,比如用 ...

  3. 乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern)

    原文:乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern) 作 ...

  4. C#设计模式:解释器模式(Interpreter Pattern)

    一,C#设计模式:解释器模式(Interpreter Pattern) 1,解释器模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易 ...

  5. python设计模式之解释器模式

    python设计模式之解释器模式 对每个应用来说,至少有以下两种不同的用户分类. [ ] 基本用户:这类用户只希望能够凭直觉使用应用.他们不喜欢花太多时间配置或学习应用的内部.对他们来说,基本的用法就 ...

  6. 设计模式之解释器模式——Java语言描述

    解释器模式提供了评估语言的语法或表达式的方式,它属于行为型模式.这种模式实现了一个表达式接口,该接口解释一个特定的上下文.这种模式被用在SQL解析.符号处理引擎等 介绍 意图 给定一个语言,定义它的文 ...

  7. JAVA设计模式之解释器模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述解释器(Interpreter)模式的: 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个 ...

  8. 20.java设计模式之解释器模式

    基本需求 实现四则运算,如计算a+b-c+d的值 先输入表达式的形式,如a+b-c+d,要求表达式正确 再分别输出a,b,c,d的值 最后求出结果 传统方案 编写一个方法,接收表达式的形式,根据用户输 ...

  9. 简单的介绍一下Java设计模式:解释器模式

    目录 定义 意图 主要解决问题 优缺点 结构 示例 适用情况 定义 解释器模式是类的行为型模式,给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器,客户端可以使用这个解释器来 ...

随机推荐

  1. Apache和PHP结合、Apache默认虚拟主机

    5月28日任务 课程内容: 11.14/11.15 Apache和PHP结合11.16/11.17 Apache默认虚拟主机 11.14/11.15 Apache和PHP结合 到目前为止虽然安装好了A ...

  2. C#程序编写高质量代码改善的157个建议[正确操作字符串、使用默认转型方法、却别对待强制转换与as和is]

    前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理解的东西,有些地方可能理解的不太到位,还望指正. 建议1. ...

  3. 使用Docker测试静态网站

    参考书籍 :第一本docker书[澳]James Turnbull  1.Sample网站的初始Dockerfile 文件目录如下: Dockerfile文件代码: 安装nginx 在容器中创建一个目 ...

  4. 消息通知机制(NSNotification和NSNotificationCenter)

    作者:FlyElephant 出处:http://www.cnblogs.com/xiaofeixiang iOS中委托模式和消息机制基本上开发中用到的比较多,一般最开始页面传值通过委托实现的比较多, ...

  5. 数据库Oracle数字函数

    数字函数不多: ROUND(arg1):四舍五入保留整数. arg1:数字类型.原数字. arg2:整数类型.小数点保留的位数. SQL> select round(1256.564,2) fr ...

  6. 源码分析—ThreadPoolExecutor线程池三大问题及改进方案

    前言 在一次聚会中,我和一个腾讯大佬聊起了池化技术,提及到java的线程池实现问题,我说这个我懂啊,然后巴拉巴拉说了一大堆,然后腾讯大佬问我说,那你知道线程池有什么缺陷吗?我顿时哑口无言,甘拜下风,所 ...

  7. Redis KeyExpire的使用

    Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key wi ...

  8. Linux—cat

    cat:查看文件内容 cat -A: 显示文件中一些比较特殊的符号,如行尾的$ cat -n:  显示行号包括空白行 cat -b:  显示行号不包括空白行

  9. RequireJS 打包工具

    r.js是RequireJS的一个附产品,支持在 NodeJS环境下运行AMD程序,并且其包含了一个名为RequireJS Optimizer的工具,可以为项目完成合并脚本等优化操作 RequireJ ...

  10. Day 09 函数

    目录 函数 函数的基本概念 为何使用函数 定义函数 什么是参数(形参,parameter) 定义函数的三种形式 无参函数 有参函数 空函数 函数的参数 形参和实参(parameter & ar ...