当前位置: 首页 > news >正文

常用设计模式系列(十五)—解释器模式

常用设计模式系列(十五)—解释器模式

第一节

前言

各位老铁大家好,郑州这两天步入了三伏天,动两步就“汗如雨下”,天气这么热,需要公司及家里都开着空调“续命”,公司到小区那五百米的距离,变成了我上班路上的绊脚石,每次出门都有一种“风萧萧兮易水寒,壮士一去兮不复返”的错觉,每次出个门都是一次挑战,有时候想着,为啥公司楼下的玻璃是透明的,当皮肤与直射的阳光接触的那一瞬间,简直不要太酸爽。
在这里插入图片描述

再热的天,再大的太阳,都能被我到手那可怜的工资的“凉凉”消化!步入正题,今天讲解的是类模式下的行为型设计模式第二节——解释器模式,解释器比较常见,在我们的JVM中,有着Java编译器和Java解释器,Java作为高级语言,计算机只能执行机器语言,故Java代码不能够被直接执行,解释器将高级语言一行一行进行解释,让计算机可以执行,这个中间对象负责的工作就是解释器。解释器模式的想法也是从解释器那参考学习过来的。

第二节

解释器模式

解释器模式(Interpreter
Pattern):提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在
SQL 解析、符号处理引擎等。

个人理解(Person
Understand):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

解释器模式组成:

在这里插入图片描述

场景举例:

我们在学习Java程序的时候,肯定学习或转义字符,当使用Java的控制台输出时,遇到“\n”就是换行,遇到“\t”就是缩进,遇到“\”则是转义,那么Java程序在读到我们所写的代码,并将代码解析并执行的过程则就是解释器模式的工作模式。

第三节

代码设计与实现
场景设计:

使用场景模拟完成解释器模式,A公司先要设计一款智能机器人,这个机器人需要指令来指示机器人完成对应的动作,那么当程序设计完成之后,通过输入指令集即可完成对机器人的控制,这个将程序指令集解释并执行的过程就是解释器模式。

场景分析:

先来分析下,机器人可以走,可以跑,跑的话是有距离的,在一个平面上,机器人可以往上下左右四个方向去跑,那么将走和跑及距离进行结合,当一个动作结束需要加另一个动作时,我们可以使用“and”字符完成连接,此时经过分析可以得到如下的分析

表达式(expression):移动方向 移动类型 移动距离
综合表达式(composite):表达式 and 表达式
移动方向(dorection):上(up)、下(down)、左(left)、右(right)
移动类型(action):走(move)、跑(run)
移动距离(distance):数字(单位米)
表达式示例:left run 10 and  up move 5(往左跑10并往上移动5)

组成设计:

1.设计抽象表达式AbstractNode2.设计终结符表达式(移动方向类)DrectionNode、移动类型类ActionNode及Distance移动距离类3.设计非终结表达式SentenceNode来完成表达式方向+类型+距离。4.编写环境角色用来解析并解释语义并调用终结表达式和非终结表达式5.编写客户端对语法进行测试

UML图:

image

代码编写:

1.设计抽象表达式AbstractNode

package com.yang.interpret;/*** @ClassName AbstractNode* @Description 抽象表达式* @Author IT小白架构师之路* @Date 2021/1/19 20:07* @Version 1.0**/
public abstract class AbstractNode {/*** 抽象方法* @return*/public abstract String interpret();
}

2.设计终结符表达式(移动方向类)DrectionNode

package com.yang.interpret;/*** @ClassName DrectionNode* @Description 移动方向类* @Author IT小白架构师之路* @Date 2021/1/19 20:10* @Version 1.0**/
public class DrectionNode extends AbstractNode {//移动方向private String direction;public DrectionNode(String direction){this.direction = direction;}@Overridepublic String interpret() {String result;switch (direction){case "up":result = "向上";break;case "down":result = "向下";break;case "left":result = "向左";break;case "right":result = "向右";break;default:result = "指令错误";break;}return result;}
}

3.设计终结符表达式,移动类型类ActionNode

package com.yang.interpret;/*** @ClassName ActionNode* @Description 移动类型* @Author IT小白架构师之路* @Date 2021/1/19 20:19* @Version 1.0**/
public class ActionNode extends AbstractNode {private String action;public ActionNode(String action){this.action = action;}@Overridepublic String interpret() {String result;switch (action){case "move":result = "走";break;case "run":result = "跑";break;default:result = "指令错误";break;}return result;}
}

4.设计终结符表达式,Distance移动距离类

package com.yang.interpret;/*** @ClassName Distance* @Description 移动距离* @Author IT小白架构师之路* @Date 2021/1/19 20:21* @Version 1.0**/
public class DistanceNode extends AbstractNode {private String distance;public DistanceNode(String distance){this.distance = distance;}@Overridepublic String interpret() {return this.distance+"米";}
}

5.设计非终结表达式SentenceNode来完成衔接

package com.yang.interpret;/*** @ClassName SentenceNode* @Description 动作衔接* @Author IT小白架构师之路* @Date 2021/1/19 20:22* @Version 1.0**/
public class SentenceNode extends AbstractNode{//移动方向private AbstractNode drectionNode;//移动类型private AbstractNode actionNode;//移动距离private AbstractNode distanceNode;public SentenceNode(AbstractNode drectionNode,AbstractNode actionNode,AbstractNode distanceNode){this.drectionNode = drectionNode;this.actionNode = actionNode;this.distanceNode = distanceNode;}@Overridepublic String interpret() {return drectionNode.interpret() + actionNode.interpret() + distanceNode.interpret();}
}

6.设计语言解释器 LanguageHandle

package com.yang.interpret;import java.util.Arrays;
import java.util.List;/*** @ClassName LanguageHandle* @Description 语法解释器* @Author IT小白架构师之路* @Date 2021/1/19 20:28* @Version 1.0**/
public class LanguageHandle {public void handle(String expression){//第一步声明三个表达式//移动方向AbstractNode drectionNode;//移动类型AbstractNode actionNode;//移动距离AbstractNode distanceNode;//组合类AbstractNode sentenceNode;//语法解析,将and进行拆分,解析综合表达式String [] arrays = expression.split(" and ");//拆分为多个表达式List<String> list = Arrays.asList(arrays);for (String temp : list){//根据空格进行拆分具体表达式String [] tempArray = temp.split(" ");//方向String direction = tempArray[0];//类型String action = tempArray[1];//距离String distance = tempArray[2];//开始解析drectionNode = new DrectionNode(direction);actionNode = new ActionNode(action);distanceNode = new DistanceNode(distance);sentenceNode = new SentenceNode(drectionNode,actionNode,distanceNode);//最终结果System.out.println(sentenceNode.interpret());}}
}

7.编写客户端测试

package com.yang.interpret;/*** @ClassName Client* @Description 客户端* @Author IT小白架构师之路* @Date 2021/1/19 20:38* @Version 1.0**/
public class Client {public static void main(String[] args) {String expression = "left run 10 and up move 5 and right run 10";LanguageHandle languageHandle = new LanguageHandle();languageHandle.handle(expression);}
}

8.测试结果

向左跑10米
向上走5米
向右跑10米

第四节

优缺点及适用场景

优点:

1.容易改变处理过程且容易扩展文法,解释器模式使用类来表示语言的文法规则,可以通过继承的机制改变或者扩展文法。

2.每一个规则都可以表示为一个类,所以可以方便的实现一个简单的语言。

3.增加新的解释表达式可通过增加新的终结符表达式或者非终结符表达式类,不需要修改原来的表达式类,符合开闭原则。

缺点:

1.如果出现较为复杂的表达式,此时文法较为复杂,当维护的时候,由于每个规则定义了一个类,如果一个类包含了许多规则,则会增加相同数量的类来做支撑,此时类的数量会变得很多,并且难以管理和维护。

2.执行效率偏低,因为解释器使用的是对字符串的拆分解析,并且使用大量的循环,当语法比较复杂时,速度会变慢。

适用场景:

1.当一个需要解释执行的语言表示为Java抽象语法树时。
2.重复出现的问题可以考虑使用简单的语法进行表达。
3.当一个语言文法比较简单,需要进行解释执行时,文法复杂时,执行效率偏低,不适合

扫描二维码

关注我吧

IT小白架构师之路

image

http://www.dtcms.com/a/302036.html

相关文章:

  • 修改CentOS的SSH登录端口(22端口)
  • python任意模块间采用全局字典来实现借用其他类对象的方法函数来完成任务或数据通信的功能
  • STM32入门之DMA直接存储器存取
  • 第4章唯一ID生成器——4.3 基于时间戳的趋势递增的唯一ID
  • Java 排序
  • LeetCode 刷题【18. 四数之和】
  • Flutter实现Android原生相机拍照
  • 如何在技术世界中保持清醒和高效
  • iphone手机使用charles代理,chls.pro/ssl 后回车 提示浏览器打不开该网页
  • NI Ettus USRP X440 软件无线电
  • 免费 SSL 证书申请简明教程,让网站实现 HTTPS 访问
  • PyTorch 使用指南
  • 基于Spring Boot的审计日志自动化解决方案,结合SpEL表达式和AOP技术,实现操作轨迹自动记录,并满足GDPR合规要求
  • <七> CentOS 8 安装最新版本Docker
  • 从零开始的云计算生活——第三十七天,跬步千里,ansible之playbook
  • LWGJL教程(8)——基础知识
  • JavaScript手录-排序算法篇
  • UNet改进(26):UNet结合分层注意力机制的图像分割深度解析
  • socketpair函数详解
  • CHI - Transaction介绍 - 其他类型介绍
  • 图论(BFS)构造邻接表(运用队列实现搜索)
  • Java面试深度剖析:从JVM到云原生的技术演进
  • 10.若依的自定义注解 Log
  • 发布“悟能”具身智能平台,商汤让机器人像人一样和现实世界交互
  • GitLab 18.2 发布几十项与 DevSecOps 有关的功能,可升级体验【一】
  • RAGFlow系列(03):把知识库通过API方式共享给Dify等外部平台使用
  • WPS 将一个PPT里面的图片和文字导入到另一个PPT中
  • CSP-J 2022_第三题逻辑表达式
  • 面试官:详细说说Kafka rebalance 的策略以及具体过程
  • 中国计算机学会(CCF)推荐学术会议-B(数据库/数据挖掘/内容检索):WSDM 2026