选择郑州网站建设/广告大全
文章目录
- 引言
- 解释器模式简介
- 定义与用途
- 实现方式
- 使用场景
- 优势与劣势
- 在Spring框架中的应用
- 表达式解析示例
- 代码地址
引言
在我们的日常生活中,语言的翻译和理解是沟通的关键。每种语言都有自己的语法规则,而翻译人员和计算机程序需要理解并遵循这些规则来正确解释语言。在软件开发领域,当我们遇到需要解释特定语言或表达式的情况时,可以使用解释器模式来处理。解释器模式提供了一种方式,使得语言的每个符号都可以通过一个解释器对象来解释执行。这在处理编程语言的编译器和解释器、规则引擎系统等领域特别有用。
解释器模式简介
定义与用途
解释器模式(Interpreter Pattern)是一种行为型设计模式,它给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。简单来说,它主要解决的是当有一个语言需要解释执行,并且可以将该语言中的句子表示为一个抽象语法树时,就可以使用解释器模式。
实现方式
实现解释器模式通常涉及以下几个关键组件:
- 抽象表达式(Abstract Expression):声明一个所有具体表达式都需要实现的抽象接口。这个接口主要是一个interpret方法,用于解释给定的上下文。
- 终结符表达式(Terminal Expression):实现与文法中的终结符相关联的解释操作。
- 非终结符表达式(Nonterminal Expression):为文法中的非终结符实现解释(Interpret)操作。
- 上下文(Context):包含解释器之外的一些全局信息。
- 客户端(Client):构建(或被给定)表示该语言中一个特定句子的抽象语法树。该抽象语法树由终结符和非终结符表达式组成。然后调用解释操作。
使用场景
解释器模式适用于以下场景:
- 当有一个语言需要解释执行,且你可以将该语言中的句子表示为一个抽象语法树时。
- 当该文法简单对于复杂的文法,文法的类层次变得庞大且无法管理时,使用解释器模式可能效率不高。
例如:
编程语言解释器和编译器:如Python解释器、Java编译器。
SQL解析:解释和执行SQL查询。
规则引擎:业务规则引擎中解释业务规则。
优势与劣势
-
优势
易于改变和扩展文法: 由于文法由许多小的类表示,所以可以比较容易地改变和扩展。
实现文法较为简单: 在正确的情况下,解释器模式可以提供一种简单的方式来实现文法。 -
劣势
对于复杂文法来说,维护一个大的抽象语法树可能比较困难。
增加了系统的复杂性和理解难度。
在Spring框架中的应用
解释器模式在Spring框架中的应用不是显而易见的,因为Spring框架主要关注于依赖注入、面向切面编程等概念。然而,可以在一些Spring功能和第三方库中找到解释器模式的影子,尤其是那些涉及到解析和执行基于一定规则的场景。
1. SpEL(Spring Expression Language)
Spring提供了一种强大的表达式语言,用于在运行时查询和操作对象图。这种语言被称为Spring Expression Language(SpEL)。SpEL使用解释器模式来解释和执行表达式。每个表达式都可以被认为是一个抽象的语法树(AST),SpEL通过遍历这个树并解释每个节点来计算表达式的值。2. 数据绑定和类型转换
Spring中的数据绑定过程需要将字符串形式的输入转换为对象的属性类型。这涉及到解析字符串并根据目标属性的类型进行转换。Spring提供了一套类型转换器,可以看作是一组解释器,每个转换器负责解释一种数据类型。3. XML配置解析
在Spring的XML配置文件中,定义了大量的标签和属性。Spring使用解析器模式来解析这些配置文件,并根据这些配置创建相应的Bean。每种标签和属性可以被看作是一种语言构造,Spring有一套解释器来解释这些构造并执行相应的操作。4. 注解处理
Spring使用注解来标识组件、注入依赖、配置事务等。处理这些注解的过程实际上是一种解释过程,Spring需要解释这些注解并根据注解执行相应的逻辑。
表达式解析示例
在这个例子中,我们定义了用于解释人名和状态的简单规则。
步骤 1:创建表达式接口
首先定义了一个 Expression 接口,作为所有具体表达式的基类。
public interface Expression {public boolean interpret(String context);
}
这个接口声明了一个interpret方法,用于解释给定的字符串上下文。
步骤 2:创建实现表达式接口的具体类
TerminalExpression
定义了一个 TerminalExpression 类,它实现了 Expression 接口,用于处理文本中的数据。
public class TerminalExpression implements Expression {private String data;public TerminalExpression(String data){this.data = data; }@Overridepublic boolean interpret(String context) {if(context.contains(data)){return true;}return false;}
}
这个类检查上下文(context)中是否包含特定的数据字符串。
OrExpression
定义了一个 OrExpression 类,它也实现了 Expression 接口,并表示逻辑或关系。
public class OrExpression implements Expression {private Expression expr1 = null;private Expression expr2 = null;public OrExpression(Expression expr1, Expression expr2) { this.expr1 = expr1;this.expr2 = expr2;}@Overridepublic boolean interpret(String context) { return expr1.interpret(context) || expr2.interpret(context);}
}
它组合了两个表达式,并在任一表达式返回true时返回true。
AndExpression
定义了一个 AndExpression 类,它同样实现了 Expression 接口,并表示逻辑与关系。
public class AndExpression implements Expression {private Expression expr1 = null;private Expression expr2 = null;public AndExpression(Expression expr1, Expression expr2) { this.expr1 = expr1;this.expr2 = expr2;}@Overridepublic boolean interpret(String context) { return expr1.interpret(context) && expr2.interpret(context);}
}
它组合了两个表达式,并要求两个表达式都返回true时才返回true。
步骤 3:使用表达式类来创建规则并解析它们
public class InterpreterPatternDemo {public static Expression getMaleExpression(){Expression robert = new TerminalExpression("Robert");Expression john = new TerminalExpression("John");return new OrExpression(robert, john); }public static Expression getMarriedWomanExpression(){Expression julie = new TerminalExpression("Julie");Expression married = new TerminalExpression("Married");return new AndExpression(julie, married); }public static void main(String[] args) {Expression isMale = getMaleExpression();Expression isMarriedWoman = getMarriedWomanExpression();System.out.println("John是男性吗? " + isMale.interpret("John"));System.out.println("Julie是已婚女性吗? " + isMarriedWoman.interpret("Married Julie"));}
}
在这个客户端中,我们创建了两个规则:一是判断一个人是否是"Robert"或"John",二是判断一个人是否是"Julie"且"Married"。然后我们测试了这些规则。
这个示例展示了如何使用解释器模式来解释和执行基于特定规则的查询。每个表达式对象代表了语言中的一个文法规则,而复杂的句子可以通过组合这些简单的表达式来解释。
代码地址
23种设计模式相关代码后续会逐步提交到github上,方便学习,欢迎指点:
代码地址
https://github.com/RuofeiSun/lf-23Pattern
相关文章:

java设计模式学习之【解释器模式】
文章目录 引言解释器模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用表达式解析示例代码地址 引言 在我们的日常生活中,语言的翻译和理解是沟通的关键。每种语言都有自己的语法规则,而翻译人员和计算机程序需要理解并遵循这些规则来…...

Unity中Shader旋转矩阵(四维旋转矩阵)
文章目录 前言一、围绕X轴旋转1、可以使用上篇文章中,同样的方法推导得出围绕X轴旋转的点阵。2、求M~rotate~ 二、围绕Y轴旋转1、可以使用上篇文章中,同样的方法推导得出围绕Y轴旋转的点阵。2、求M~rotate~ 三、围绕Z轴旋转1、可以使用上篇文章中&#x…...

【大数据】Centos 7安装教程
一、下载VMware 大家可以通过浏览器进入官网下载VMware,下载后打开VMware进行安装。 二、下载镜像的方式 1、进入Centos官网下载 2、进入阿里云、华为云镜像站下载 以阿里云为例,这里有很多,比如ubuntu、centos,点进去就可以选…...

2024 年 11 款最佳 Android 数据恢复软件应用
Android 设备上的数据丢失可能是一种令人痛苦的经历,通常会导致不可替代的信息瞬间消失。 意外删除、系统崩溃或格式错误都可能发生,重要数据的丢失可能会扰乱日常工作并影响您的工作效率。 幸运的是,技术进步带来了多种恢复解决方案&…...

Redis 核心知识总结
Redis 核心知识总结 认识 Redis 什么是 Redis? Redis 是一个由 C 语言开发并且基于内存的键值型数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常用于缓存,消息队列、分布式锁等场景。 有以下几个特…...

Android Jetpack之用Room+ViewModel+LiveData实现增删改查数据(createFromAsset())
文章目录 一、Room简介二、用RoomViewModelLiveData增删改查数据三、下载源码 一、Room简介 Room是Google推出的数据库框架,是一个 ORM (Object Relational Mapping)对象关系映射数据库、其底层还是对SQLite的封装。 Room包含三个主要组件: 数据库类&…...

MySQL ORDER BY(排序) 语句-读取的数据进行排序
MySQL ORDER BY(排序) 语句 我们知道从 MySQL 表中使用 SELECT 语句来读取数据。 如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。 MySQL ORDER BY(排序) 语句可以…...

【ES】es介绍
倒排索引(Inverted Index)和正排索引(Forward Index) 正排索引是一种以文档为单位的索引结构,它将文档中的每个单词或词组与其所在的文档进行映射关系的建立。正排索引通常用于快速检索指定文档的内容,可以…...

07.kubernetes客户端部署
kubernetes 客户端部署 主要是配置 kubectl 完成以下两个操作: 首先是要实现通过命令行连接到Kubernetes的apiserver然后就是创建必要的 ClusterRoleBinding 实现 kubelet bootstrapping CSR 的自动验签kubelet bootstrapping主要涉及以下两个问题,官方文档已经给出详细的介…...

laravel5.8中实现验证码组件的安装和验证
本篇文章主要讲解使用laravel5.8自带的验证码库实现验证码验证的效果教程。通过本教程你可以快速接入到自己的项目中开发相应的验证功能。 作者:任聪聪 (rccblogs.com) 日期:2023年12月17日 实际效果 安装步骤 步骤一、输入命令 composer require mews…...

使用VScode通过内网穿透在公网环境下远程连接进行开发
文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…...

常用的 linux 命令
常用的 linux 命令 1.从其他机器拷贝文件夹2.查看哪个程序在用特定端口3.实时监控日志文件内容4.查看指定用户拥有的进程5.查看磁盘空间使用情况6.文件搜索which(whereis) 显示系统命令所在目录find 查找任何文件或目录1) 根据文件名称查找2)…...

[论文阅读笔记28] 对比学习在多目标跟踪中的应用
这次做一篇2D多目标跟踪中使用对比学习的一些方法. 对比学习通过以最大化正负样本特征距离, 最小化正样本特征距离的方式来实现半监督或无监督训练. 这可以给训练MOT的外观特征网络提供一些启示. 使用对比学习做MOT的鼻祖应该是QDTrack, 本篇博客对QDTrack及其后续工作做一个总…...

Ubuntu 下播放语音提示
目录 一、安装语音库 二、生成音频文件 三、语音播放代码 一、安装语音库 sudo apt update apt-get install libasound2-dev二、生成音频文件 # 文字生成 MP3网地:https://www.text-to-speech.cn/# MP3 转 WAV网址:https://www.aconvert.com/cn/aud…...

ubuntu 用户管理
ubuntu 用户管理 用户组管理用户管理VNC 远程桌面参考 用户组管理 # 查看所有组信息 cat /etc/group # 查看当前用户所在组 groups # 添加用户组 sudo groupadd uav# 添加ostest用户到 uav 用户组 需要注销并重新登录 sudo gpasswd -a ostest uav sudo usermod -aG uav ostes…...

轻舟已过万重山,鸿蒙4.0程序员危机
现在是2023年末。自从华为推出的鸿蒙系统到现在已经有4年多。之前的鸿蒙系统只是基于Android套壳,因为这也也被无数人瞧不起,自从华为秋季发布会后,宣布鸿蒙4.0问世。不再兼容Android,华为做独立的系统终于打了翻身仗。 鸿蒙系统…...

【Pytorch】学习记录分享6——PyTorch经典网络 ResNet与手写体识别
【Pytorch】学习记录分享5——PyTorch经典网络 ResNet 1. ResNet (残差网络)基础知识2. 感受野3. 手写体数字识别3. 0 数据集(训练与测试集)3. 1 数据加载3. 2 函数实现:3. 3 训练及其测试: 1. ResNet &…...

Flink1.17实战教程(第三篇:时间和窗口)
系列文章目录 Flink1.17实战教程(第一篇:概念、部署、架构) Flink1.17实战教程(第二篇:DataStream API) Flink1.17实战教程(第三篇:时间和窗口) Flink1.17实战教程&…...

CSS 纵向扩展动画
上干货 <template><!-- mouseenter"startAnimation" 表示在鼠标进入元素时触发 startAnimation 方法。mouseleave"stopAnimation" 表示在鼠标离开元素时触发 stopAnimation 方法。 --><!-- 容器元素 --><div class"container&q…...

Android 12 Token 机制
一、前言 在 android framework 框架中 activity 和 window 是相互关联的,而他们的管理者 AMS 和 WMS 是怎么来实现这种关联关系的,答案就是通过 token。 首先大家需要了解一下 LayoutParams,当然属性很多,简单了解即可…...

TCP与UDP是流式传输协议吗?
TCP(传输控制协议)和UDP(用户数据报协议)是两种主要的传输层协议,它们用于在网络中传输数据。它们不是流式传输协议,而是提供了不同的数据传输特性: 1. TCP(传输控制协议࿰…...

61 贪心算法解救生艇问题
问题描述:第i个人的体重为peaple[i],每个船可以承载的最大重量为limit。每艘船最多可以同时载两人,但条件是这些人的重量之和最多为limit,返回载到每一个人多虚的最小船数,(保证每个人被船载)。 贪心算法求解:先将数组…...

C#高级 01.Net多线程
一.基本概念 1.什么是线程? 线程是操作系统中能独立运行的最小单位,也是程序中能并发执行的一段指令序列线程是进程的一部分,一个进程可以包含多个线程,这些线程共享进程资源进程有线程入口,也可以创建更多的线程 2.…...

Java---泛型讲解
文章目录 1. 泛型类2. 泛型方法3. 泛型接口4. 类型通配符5. 可变参数6. 可变参数的使用 1. 泛型类 1. 格式:修饰符 class 类名 <类型>{ }。例如:public class Generic <T>{ }。 2. 代码块举例: public class Generic <T>{…...

【论文阅读笔记】SegVol: Universal and Interactive Volumetric Medical Image Segmentation
Du Y, Bai F, Huang T, et al. SegVol: Universal and Interactive Volumetric Medical Image Segmentation[J]. arXiv preprint arXiv:2311.13385, 2023.[代码开源] 【论文概述】 本文思路借鉴于自然图像分割领域的SAM,介绍了一种名为SegVol的先进医学图像分割模型…...

Unix/Linux操作系统介绍
1、Unix/Linux操作系统介绍 1.1、操作系统的作用 1)操作系统的目标 方便:使计算机系统易于使用有效:以更有效的方式使用计算机系统资源扩展:方便用户有效开发、测试、引进新功能 2)操作系统的地位 操作系统在计算…...

什么是https证书?
HTTPS证书,也称为SSL(Secure Sockets Layer)证书或TLS(Transport Layer Security)证书,是一种数字证书,用于在网络上建立安全的加密连接。它的主要目的是确保在互联网上进行的数据传输的安全性和…...

C++ DAY2作业
1.课堂struct练习,用class; #include <iostream>using namespace std;class Stu { private:int age;char sex;int high; public:double score;void set_values(int a,char b,int c,double d);int get_age();char get_sex();int get_high(); }; vo…...

RabbitMQ核心概念记录
本文来记录下RabbitMQ核心概念 文章目录 什么叫消息队列为何用消息队列RabbitMQ简介RabbitMQ基本概念RabbitMQ 特点具体特点包括 Rabbitmq的工作过程RabbitMQ集群RabbitMQ 的集群节点包括Rabbit 模式大概分为以下三种单一模式普通模式镜像模式 本文小结 什么叫消息队列 消息&am…...

算法时间空间复杂度计算—空间复杂度
算法时间空间复杂度计算—空间复杂度 空间复杂度定义影响空间复杂度的因素算法在运行过程中临时占用的存储空间讲解 计算方法例子1、空间算法的常数阶2、空间算法的线性阶(递归算法)3、二分查找分析方法一(迭代法)方法二ÿ…...