【设计模式】我终于读懂了解释器模式。。。

✒️四则运算问题

通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求

  1. 1. 先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复

  2. 2. 在分别输入 a ,b, c, d, e 的值

  3. 3. 最后求出结果:如图

【设计模式】我终于读懂了解释器模式。。。

✒️传统方案解决四则运算问题分析

  1. 1. 编写一个方法,接收表达式的形式,然后根据用户输入的数值进行解析,得到结果

  2. 2. 问题分析:如果加入新的运算符,比如 * / ( 等等,不利于扩展,另外让一个方法来解析会造成程序结构混乱, 不够清晰.

  3. 3. 解决方案:可以考虑使用解释器模式, 即: 表达式 -> 解释器(可以有多种) -> 结果

    ✒️解释器模式基本介绍

  4. 4. 在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器

  5. 5. 解释器模式(Interpreter Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器, 使用该解释器来解释语言中的句子(表达式)

  6. 6. 应用场景

  • • 应用可以将一个需要解释执行的语言中的句子表示为一个抽象语法树

  • • 一些重复出现的问题可以用一种简单的语言来表达

  • • 一个简单语法需要解释的场景

  1. 1. 这样的例子还有,比如编译器、运算表达式计算、正则表达式、机器人等

✒️解释器模式的原理类图

【设计模式】我终于读懂了解释器模式。。。

✒️对原理类图的说明-即(解释器模式的角色及职责)

  1. 1. Context: 是环境角色,含有解释器之外的全局信息.

  2. 2. AbstractExpression: 抽象表达式, 声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享

  3. 3. TerminalExpression: 为终结符表达式, 实现与文法中的终结符相关的解释操作

  4. 4. NonTermialExpression: 为非终结符表达式,为文法中的非终结符实现解释操作.

  5. 5. 说明:输入 Context he TerminalExpression 信息通过 Client 输入即可

✒️解释器模式来实现四则

  1. 1. 应用实例要求 通过解释器模式来实现四则运算, 如计算 a+b-c 的值

  2. 2. 思路分析和图解(类图)

【设计模式】我终于读懂了解释器模式。。。
【设计模式】我终于读懂了解释器模式。。。

Expression类

【设计模式】我终于读懂了解释器模式。。。

VarExpression类,继承Expression类

【设计模式】我终于读懂了解释器模式。。。

SymbolExpression类,继承Expression类

【设计模式】我终于读懂了解释器模式。。。

AddExpression类,继承SymbolExpression类

【设计模式】我终于读懂了解释器模式。。。

SubExpression类,继承SymbolExpression类

【设计模式】我终于读懂了解释器模式。。。

Calculator类,可以理解成一个工具类,加不加都无所谓,不影响该模式的结构

【设计模式】我终于读懂了解释器模式。。。

Client类,客户端类

【设计模式】我终于读懂了解释器模式。。。

运行结果

【设计模式】我终于读懂了解释器模式。。。

✒️debug看原理

我们主要看设计模式的运行方式,程序的代码我们就没有必要深究了

通过我们的方法接收到了表达式和对应的值

【设计模式】我终于读懂了解释器模式。。。

我们进入Calculator()构造方法

【设计模式】我终于读懂了解释器模式。。。

创建了一个栈

【设计模式】我终于读懂了解释器模式。。。

这里根据字符是+我们调用了AddExpression的构造方法,将VarExpression的实例传入到构造方法中去

【设计模式】我终于读懂了解释器模式。。。

-则是SubExpression的构造函数

遍历完之后我们的表达式就被解析成了这样

【设计模式】我终于读懂了解释器模式。。。
【设计模式】我终于读懂了解释器模式。。。

然后调用run方法

【设计模式】我终于读懂了解释器模式。。。
【设计模式】我终于读懂了解释器模式。。。

走的是SubExpression的interpreter方法

【设计模式】我终于读懂了解释器模式。。。

然后调用AddExpression的interpreter方法,就是计算a+b的结果,从右开始遍历

【设计模式】我终于读懂了解释器模式。。。

到AddExpression的interpreter方法之后,走的是VarExpression的interpreter方法

【设计模式】我终于读懂了解释器模式。。。

返回a对应的值

【设计模式】我终于读懂了解释器模式。。。

右节点则返回20

【设计模式】我终于读懂了解释器模式。。。

SubExpression左节点得到值:30

【设计模式】我终于读懂了解释器模式。。。

右节点是VarExpression解释器,会返回对应的值

【设计模式】我终于读懂了解释器模式。。。

得到25

【设计模式】我终于读懂了解释器模式。。。

计算完成,得到结果:5

【设计模式】我终于读懂了解释器模式。。。
【设计模式】我终于读懂了解释器模式。。。

✒️解释器模式在Spring 框架应用的源码剖析

  1. 1. Spring 框架中 SpelExpressionParser 就使用到解释器模式

  2. 2. 代码分析+Debug 源码

【设计模式】我终于读懂了解释器模式。。。

SpelExpressionParser类

【设计模式】我终于读懂了解释器模式。。。

调用parseExpression方法

【设计模式】我终于读懂了解释器模式。。。

根据参数的不同返回不同的解释器

【设计模式】我终于读懂了解释器模式。。。

当前情况返回的是SpelExpression解释器

【设计模式】我终于读懂了解释器模式。。。

如果是另外一种情况则返回CompositeStringExpression解释器

【设计模式】我终于读懂了解释器模式。。。
【设计模式】我终于读懂了解释器模式。。。

✒️Expression接囗表达式接囗

下面有不同的实现类,比如SpelExpression或compositeStringExpression。使用时候,根据你创建的不同的Parser对象,返回不同的Expression对象

✒️解释器模式的注意事项和细节

  1. 1. 当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性

  2. 2. 应用场景:编译器、运算表达式计算、正则表达式、机器人等

  3. 3. 使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低.

资料参考:https://www.bilibili.com/video/BV1G4411c7N4

代码地址:https://gitee.com/WangFuGui-Ma/design-pattern/tree/master/design


【设计模式】我终于读懂了解释器模式。。。

另外如果对Elastic Search感兴趣的话,推荐一下我的专栏,这篇专栏介绍了Elasticsearch的Restful API的入门指南。学习如何使用API进行索引、搜索和分析,包括创建索引、定义映射、添加文档、执行查询等。通过实例和代码片段,快速上手Elasticsearch的Restful API,构建强大的搜索功能。感谢大家支持:

Elastic Search的RestFul API入门 [1]

【设计模式】我终于读懂了解释器模式。。。

引用链接

[1] Elastic Search的RestFul API入门 : https://blog.csdn.net/csdnerm/category_12497418.html


原文始发于微信公众号(掉头发的王富贵):【设计模式】我终于读懂了解释器模式。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/297320.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!