设计模式 15 解释器模式

设计模式 15

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • 设计模式 15
    • 解释器模式(Interpreter Pattern)
      • 1 定义
      • 2 结构
      • 3 示例代码
      • 5 特点
      • 6 适用场景
      • 7 总结

解释器模式(Interpreter Pattern)

1 定义

解释器模式通过定义一种语言的语法规则,使用这些规则解析和执行语言中的语句。这种模式通常用于那些具有简单语法和小型命令集的领域特定语言(DSL)中。

2 结构

解释器模式包含以下角色:

  • 抽象表达式(AbstractExpression): 声明解释操作,接口或抽象类。
  • 终结符表达式(TerminalExpression): 实现与语法规则相关的操作,处理语法中的终结符。
  • 非终结符表达式(NonTerminalExpression): 表示语法规则中的非终结符,通常包含一个或多个表达式。
  • 上下文(Context): 包含解释器需要的全局信息。
  • 客户端(Client): 构建或解释语法规则,并使用解释器来解释语句。

UML 类图

+---------------------------------------+
|  AbstractExpression                   |  <----- 抽象表达式
+---------------------------------------+
| + Interpret(context: Context): void   |
+---------------------------------------+^|
+---------------------------------------+    +---------------------------------------+
| TerminalExpression                    |    | NonTerminalExpression                 |
+---------------------------------------+    +---------------------------------------+
| + Interpret(context: Context): void   |    | + Interpret(context: Context): void   |
+---------------------------------------+    +---------------------------------------++-------------------+
|     Context       |  <----- 上下文
+-------------------+
| + GetInfo(): ...  |
+-------------------+

3 示例代码

假设我们要实现一个简单的数学表达式解释器,可以解析和计算简单的加法和减法运算表达式。

抽象表达式

// 抽象表达式
public interface IExpression
{int Interpret();
}

终结符表达式

// 终结符表达式:数字
public class NumberExpression : IExpression
{private readonly int _number;public NumberExpression(int number){_number = number;}public int Interpret(){return _number;}
}

非终结符表达式

// 非终结符表达式:加法
public class AddExpression : IExpression
{private readonly IExpression _leftExpression;private readonly IExpression _rightExpression;public AddExpression(IExpression leftExpression, IExpression rightExpression){_leftExpression = leftExpression;_rightExpression = rightExpression;}public int Interpret(){return _leftExpression.Interpret() + _rightExpression.Interpret();}
}// 非终结符表达式:减法
public class SubtractExpression : IExpression
{private readonly IExpression _leftExpression;private readonly IExpression _rightExpression;public SubtractExpression(IExpression leftExpression, IExpression rightExpression){_leftExpression = leftExpression;_rightExpression = rightExpression;}public int Interpret(){return _leftExpression.Interpret() - _rightExpression.Interpret();}
}

客户端代码

class Program
{static void Main(string[] args){// 构造表达式:10 + 5 - 2IExpression expression = new SubtractExpression(new AddExpression(new NumberExpression(10), new NumberExpression(5)),new NumberExpression(2));// 解释并计算结果int result = expression.Interpret();Console.WriteLine($"Result: {result}");}
}

运行结果

Result: 13

在这个例子中,表达式 10 + 5 - 2 被构造为一个解释器树,并通过调用 Interpret 方法递归地计算出结果。NumberExpression 是终结符表达式,用于表示具体的数字值,AddExpressionSubtractExpression 是非终结符表达式,用于表示加法和减法操作。

5 特点

  • 优点:

    • 灵活性高: 解释器模式使得设计自定义语言变得更加容易,通过组合不同的表达式类可以实现复杂的语法解析。

    • 可扩展性好: 新的语法规则可以通过添加新的表达式类来实现,而不需要修改现有的系统。

  • 缺点:

    • 性能问题: 解释器模式适用于语法规则相对简单的场景。对于复杂的语法解析,由于要递归解析表达式树,可能会导致性能问题。

    • 类的数量增加: 每个语法规则都需要一个类来实现,可能导致类的数量急剧增加,增加了系统的复杂性。

6 适用场景

  • 简单的语言解释器: 如脚本语言解释器、配置文件解析器、规则引擎等。
  • 编译器设计: 在编译器中使用解释器模式来解析和解释源代码。
  • 复杂的数据解析: 需要解释和执行复杂的命令或数据时,使用解释器模式来解析并执行。

7 总结

解释器模式通过定义语言的语法规则,并使用这些规则解析和执行语句。它适用于简单的语法规则和小型语言解析任务,但不适用于复杂的语法解析和大规模系统。解释器模式的灵活性和扩展性使其在某些领域特定语言的实现中非常有用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 什么是属性

1.属性Aproperty)是一种用于访问对象或类型的特征的成员,特征反映了状态 2.属性是字段的自然扩展 从命名上看,field更偏向于实例对象在内存中的布局,property更偏向于反映现实世界对象的特征对外:暴露数据,数据可以是存储在字段里的,也可以是动态计算出来的对内:保护字段不被…

基于机器学习的商品评论情感分析

从淘宝爬取评论 使用Selenium模拟真实登录行为&#xff0c;并爬取数据。 数据清理 如果文本中有“666“&#xff0c;”好好好“等无用词语&#xff0c;去掉评论中的标点符号。 分词 使用jieba精确模式进行分词&#xff0c;构造词典 将词汇向量化 创建词语字典&#xff0c;并…

Java技术栈 —— Spark入门(三)之实时视频流

Java技术栈 —— Spark入门&#xff08;三&#xff09;之实时视频流转灰度图像 一、将摄像头数据发送至kafka二、Kafka准备topic三、spark读取kafka图像数据并处理四、本地显示灰度图像(存在卡顿现象&#xff0c;待优化) 项目整体结构图如下 参考文章或视频链接[1] Architectur…

python自动化脚本:让工作自动化起来

Python是一种流行的编程语言&#xff0c;以其简洁和易读性而闻名。它提供了大量的库和模块&#xff0c;使其成为自动化各种任务的绝佳选择。 我们将探讨9个Python脚本及其代码&#xff0c;可以帮助您自动化各种任务并提高工作效率。无论您是开发人员、数据分析师还是只是想简化…

Python-MNE-源空间和正模型07:修复BEM和头表面

有时在创建BEM模型时&#xff0c;由于可能出现的一系列问题(例如&#xff0c;表面之间的交叉)&#xff0c;表面需要手动校正。在这里&#xff0c;我们将看到如何通过将表面导出到3D建模程序blender&#xff0c;编辑它们&#xff0c;并重新导入它们来实现这一点。我们还将给出一…

Java 入门指南:初识 Java 并发编程

何为并发编程 并发编程是指在程序中同时执行多个任务的一种编程方式。它通常用于提高程序的性能和响应时间。 在传统的单线程编程模型中&#xff0c;每次只能执行一个任务&#xff0c;当任务阻塞或耗时较长时&#xff0c;整个程序会变得缓慢。而并发编程则可以通过同时执行多…

鸿蒙(API 12 Beta3版)【通过字节数组生成码图】

基本概念 码图生成能力支持将字节数组转换为自定义格式的码图。 场景介绍 码图生成能力支持将字节数组转换为自定义格式的码图。 例如&#xff1a;调用码图生成能力, 将字节数组转换成交通一卡通二维码使用。 约束与限制 只支持QR Code生成&#xff0c;根据纠错水平不同对…

LuaJit分析(七)LuaJit -b 命令分析

Luajit -b 命令用于生成字节码文件&#xff0c;通过之前对 -bl命令的分析&#xff1a; luajit -bl 命令分析 可知&#xff0c;-b系统的命令都通过执行 bcsave.lua脚本来完成&#xff0c; luajit -b命令最终是执行bcsave.lua脚本中的 bcsave函数&#xff0c;bcsave函数代码如下…

【已解决】win11笔记本电脑突然无法检测到其他显示器 / 无法使用扩展屏(2024.8.29 / 驱动更新问题)

我们点击 winx &#xff0c;找到设备管理器&#xff0c;查看显示适配器&#xff1a; 主要问题就出现在 NVIDIA GeForce RTX 3060 Laptop GPU 上&#xff08;虽然我把所有驱动都重新更新了一遍&#x1f62d;&#xff09;。 常用驱动更新&#xff1a; dell 驱动更新&#xff08…

深入解析Nginx的Fair调度算法:实现请求的智能分配

在Web服务器和负载均衡器的领域&#xff0c;Nginx以其高性能和灵活性而闻名。Nginx提供的负载均衡模块支持多种调度算法&#xff0c;其中fair算法是一种动态分配请求的方法&#xff0c;它根据后端服务器的响应时间来智能地分配请求。本文将详细介绍Nginx的fair调度算法的工作原…

android 14及android15 READ_EXTERNAL_STORAGE跟相册,视频权限的适配

最近在做Android15的适配&#xff0c;发现WRITE_EXTERNAL_STORAGE跟READ_EXTERNAL_STORAGE无法使用了&#xff0c;被弃用了 在android 13添加了外部细分权限&#xff0c;READ_MEDIA_IMAGES跟READ_MEDIA_VIDEO及 READ_MEDIA_AUDIO权限&#xff0c;而在应用内部的文件管理则不需要…

HTML <template> 标签的基本技巧

前言 HTML中的<template>标记是 Web 开发中一个功能强大但经常未得到充分利用的元素。它允许你定义可重复使用的内容&#xff0c;这些内容可以克隆并插入 DOM 中而无需最初渲染。 此功能对于创建动态、交互式 Web 应用程序特别有用。 在本文中&#xff0c;我们将探讨有…

排序算法之希尔排序详细解读(附带Java代码解读)

希尔排序&#xff08;Shell Sort&#xff09;是一种基于插入排序的改进算法&#xff0c;它通过将待排序的数组分成若干个子数组&#xff0c;并对这些子数组进行插入排序&#xff0c;从而提高整体排序效率。希尔排序的主要思想是利用分组的方式来减少元素之间的移动距离&#xf…

STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压

STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压&#xff1a;PC0、PA1和PA2。本测试将ADC1_IN6映射到PC0引脚&#xff0c;ADC12_IN2映射到PA1引脚&#xff0c;ADC1_IN3映射到PA2引脚。 1、ADC输入 ADC输入电压范围&#xff1a;Vref– ≤ VIN ≤ Vref ADC支持“单端输入…

C#面:ActionResult 和 ViewResult有什么不同?

ActionResult 和 ViewResult 是 ASP.NET MVC 中的两个重要的类&#xff0c;用于处理控制器方法的返回结果。 ActionResult&#xff1a;是一个抽象基类&#xff0c;表示控制器方法的返回结果。它提供了一系列派生类&#xff0c;如ViewResult、RedirectResult、JsonResult 等&am…

突破编程:C++中的组合模式(Composite Pattern)

突破编程&#xff1a;C中的组合模式&#xff08;Composite Pattern&#xff09; 在软件设计领域&#xff0c;组合模式&#xff08;Composite Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式让客户…

顺序表和链表知识点

1 顺序表 顺序表是指用一段物理地址连续的空间去存储数据的线性结构。 顺序表有两种&#xff1a;静态顺序表&#xff0c;动态顺序表。 1.1 静态顺序表结构体定义 typedef int ElemDataSL;typedef struct SequeList {ElemDataSL arr[100];int size; }SL; 静态顺序表在创建结构体…

【 html+css 绚丽Loading 】000026 五行吞灵盘

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

数学建模学习(120):使用Python实现基于AHP的供应商选择分析

AHP为很多比赛中常用到的方法。以案例学习方法,大家要认真理解案例和代码,代码和思维是通用的。 文章目录 1.引言2. 案例:供应商选择2.1 问题描述2.2 决策的层次结构3. AHP 方法的理论背景4. 案例应用:供应商选择的 AHP 实现4.1 建立成对比较矩阵4.2 准则的成对比较矩阵4.3…

介绍一下KAFKA的ACK机制?

在Apache Kafka中&#xff0c;ACK&#xff08;Acknowledgment&#xff09;机制是用于确保消息被成功写入Kafka集群中并被复制&#xff08;如果有启用复制功能&#xff09;的重要部分。Kafka的ACK机制允许生产者&#xff08;Producer&#xff09;和消费者&#xff08;Consumer&a…