java设计模式学习之【解释器模式】

文章目录

  • 引言
  • 解释器模式简介
    • 定义与用途
    • 实现方式
  • 使用场景
  • 优势与劣势
  • 在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2660155.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【将G2O库使用交叉编译移植到arm平台】

一 准备材料 1.下载好g2o的代码。下载地址:https://github.com/RainerKuemmerle/g2o 如果只是在Ubuntu系统上安装g2o,可以参考代码库中的readme.md。 2.下载suitesparse4.4.6. 选择4.4.6版本是因为我发现ROS系统中使用的是这个版本。即使用sudo apt-get …

【Vulnhub 靶场】【Looz: 1】【简单】【20210802】

1、环境介绍 靶场介绍:https://www.vulnhub.com/entry/looz-1,732/ 靶场下载:https://download.vulnhub.com/looz/Looz.zip 靶场难度:简单 发布日期:2021年08月02日 文件大小:2.1 GB 靶场作者:mhz_cyber &…

c语言:输出范围内的质数|练习题

一、题目 输入一个数n,输出n之内的所有质数 如图: 二、思路分析 1、设置一个数num,从2开始,不断作1操作,作为被除数 2、用一个不断自1的数,除以num,如果num不能被整除,则为质数 3、例…

超分之SRGAN

Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network使用生成对抗网络的逼真单图像超分辨率一作:Christian Ledig是Twitter2017年的一篇论文。 文章目录 0. 摘要1. 引言1.1 相关工作1.1.1 介绍了SR技术的发展历程1.1.2 介绍了SR…

算法基础day2

前缀和 #include <iostream> using namespace std; const int N100010; int n,m; int a[N],s[N]; int main() {scanf("%d%d",&n,&m);for(int i1;i<n;i) scanf("%d",&a[i]);for(int i1;i<n;i) s[i]s[i-1]a[i];while(m--){int l,r;s…

模型系列:增益模型Uplift Modeling原理和案例

模型系列&#xff1a;增益模型Uplift Modeling原理和案例 目录 1. 简介1. 第一步2. 指标3. 元学习器 3.1 S-学习器3.2 T-学习器3.3 T-学习器相关模型 简介 Uplift是一种用于用户级别的治疗增量效应估计的预测建模技术。每家公司都希望增加自己的利润&#xff0c;而其中一个…

Python+OpenCV 零基础学习笔记(6):ROI

文章目录 相关链接运行环境前言ROI颜色区域分割颜色通道合并 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程 CSDN标题里个括号对应视频的分P OpenCVPython CSDN专栏 Gitee 项目地址 运行环境 Python:3.11.5Anaconda:23.7.4IDE:vscode运行环境&#x…

链表:如何利用“假头,新指针,双指针”解决链表问题

Java学习面试指南&#xff1a;https://javaxiaobear.cn 链表是一种线性数据结构&#xff0c;其中的每个元素实际上是一个单独的对象&#xff0c;而所有对象都通过每个元素中的引用字段链接在一起。 链表是一种物理存储单元上非连续、非顺序的存储结构&#xff0c;其物理结构不能…

深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第六节 理解垃圾回收GC,提搞程序性能

深入浅出图解C#堆与栈 C# Heaping VS Stacking 第六节 理解垃圾回收GC&#xff0c;提搞程序性能 [深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第一节 理解堆与栈](https://mp.csdn.net/mdeditor/101021023)[深入浅出图解C#堆与栈 C# Heap(ing) VS Stack(ing) 第二节 栈基…

【kubernetes】集群网络(一):基础篇

Flannel 1 路由表 & arp & fdb 1.1 路由表 任何网络设备都需要路由表&#xff0c;路由表用来决定&#xff0c;当收到数据包时&#xff0c;该向哪里进行转发。路由表项通常会包含以下几个字段&#xff1a; Destination&#xff1a;目的地Gateway&#xff1a;网关Mas…

12.27重构二叉树,插入排序,队列(股票,模拟),后缀表达式求值,括号匹配,验证栈序列,选择题部分

重构二叉树 误 string in, post; struct node {char a;node* lchild, * rchild;node(char x\0) :a(x), lchild(nullptr), rchild(nullptr) {} }; void so(node* r, int il, int ir, int pl, int pr) {if (il > ir)return;int root;for (root il; root < ir; root) {if…

[AI编程]AI辅助编程助手-亚马逊AI 编程助手 Amazon CodeWhisperer

亚马逊AI 编程助手 Amazon CodeWhisperer 是一种基于人工智能技术的编程辅助工具&#xff0c;旨在帮助开发人员更高效地编写代码。它可以提供实时的代码建议、自动补全和错误检查&#xff0c;帮助优化代码质量和提高编程效率。 Amazon CodeWhisperer 使用了自然语言处理和机器…

OpenChat-3.5:70亿参数下的AI突破

引言 在对话AI的发展史上&#xff0c;OpenChat-3.5标志着一个新纪元的到来。拥有70亿参数的这一模型&#xff0c;不仅是对现有语言学习模型&#xff08;LLMs&#xff09;的重大改进&#xff0c;更是在多模态任务中树立了新的标准。 模型概述 OpenChat-3.5作为一款先进的多模…

Leetcode—1572.矩阵对角线元素的和【简单】

2023每日刷题&#xff08;七十三&#xff09; Leetcode—1572.矩阵对角线元素的和 实现代码 class Solution { public:int diagonalSum(vector<vector<int>>& mat) {int n mat.size();if(n 1) {return mat[0][0];}int sum 0;int i 0, j n - 1;while(i &…

ARM CCA机密计算软件架构之RMI领域管理接口与RSI领域服务接口

领域管理接口 领域管理接口&#xff08;RMI&#xff09;是RMM与正常世界主机之间的接口。 RMI允许正常世界虚拟机监视器向RMM发出指令&#xff0c;以管理领域。 RMI使用来自主机虚拟机监视器的SMC调用&#xff0c;请求RMM的管理控制。 RMI使得对领域管理的控制成为可能&…

自动化测试框架知识总结(超详细整理)

一、什么是自动化测试框架 在了解什么是自动化测试框架之前&#xff0c;先了解一下什么叫框架&#xff1f;框架是整个或部分系统的可重用设计&#xff0c;表现为一组抽象构件及构件实例间交互的方法;另一种定义认为&#xff0c;框架是可被应用开发者定制的应用骨架。前者是从应…

Java多线程常见的成员方法(线程优先级,守护线程,礼让/插入线程)

目录 1.多线程常见的成员方法2.优先级相关的方法3.守护线程&#xff08;备胎线程&#xff09;4.其他线程 1.多线程常见的成员方法 ①如果没有给线程设置名字&#xff0c;线程是有默认名字 的&#xff1a;Thread-X(X序号&#xff0c;从0开始) ②如果要给线程设置名字&#xff0c…

10 分钟了解 nextTick ,并实现简易版的 nextTick

前言 在 Vue.js 中&#xff0c;有一个特殊的方法 nextTick&#xff0c;它在 DOM 更新后执行一段代码&#xff0c;起到等待 DOM 绘制完成的作用。本文会详细介绍 nextTick 的原理和使用方法&#xff0c;并实现一个简易版的 nextTick&#xff0c;加深对它的理解。 一. 什么是 n…

sql优化,内外连接有什么区别

内外连接是啥不必多说&#xff0c;但在做关联查询的时候&#xff0c;二者是有一些区别的&#xff1a; 举例来说&#xff0c;首先是外连接&#xff08;左外连接为例&#xff09;&#xff0c;当两个表都没有索引&#xff0c;就都是全表扫描 EXPLAIN SELECT SQL_NO_CACHE * FROM …

19个Python语法糖和9个内置装饰器

19 个Sweet的 Python Syntax Sugar&#xff0c;用于改善您的编码体验 文章目录 19 个Sweet的 Python Syntax Sugar&#xff0c;用于改善您的编码体验1. 联合运算符Union Operators&#xff1a;合并 Python 字典的最优雅方式2. 类型提示Type Hints&#xff1a;使您的 Python 程序…