设计模式 解释器模式(Interpreter Pattern)

news2024/9/22 9:58:00

文章目录

    • 解释器模式简绍
    • 解释器模式的结构
    • 优缺点
    • UML图
    • 具体代码实现
        • Context 数据实体类,可以包含一些方法
        • Abstract Expression 创建接口方法
        • Terminal Expression 对数据简单处理
        • Non-Terminal Expression 同样实现抽象接口方法
        • Client(客户端) 调用方法

解释器模式简绍

解释器模式(Interpreter Pattern)是一种软件设计模式,属于行为型模式之一。这种模式的主要目的是定义语言的语法表示,并且提供了一个解释器来处理这种表示。解释器模式可以用于解析语言或表达式等场合,特别是在编译器、解释器和自然语言处理中应用较多。

解释器模式的结构

解释器模式包含以下几个主要角色:

  • Abstract Expression(抽象表达式):
    • 这是所有表达式的公共接口或抽象类,它定义了所有非终端表达式和终端表达式所需要的方法,通常是interpret()方法。
  • Terminal Expression(终端表达式):
    • 实现了抽象表达式接口,负责处理文法中的文字符号,例如单词或数字等。
  • Non-Terminal Expression(非终端表达式):
    • 同样实现了抽象表达式接口,但它除了包含对文法符号的处理外,还包含对多个表达式的组合处理逻辑。
  • Context(环境):
    • 包含解释器之外的一些全局数据或者局部数据,供解释器解释过程中使用。
  • Client(客户端):
    • 构造一个完整的文法树,然后给定一个具体的上下文环境,最后调用解释方法。

优缺点

  • 解释器模式的优点
    • 增加了新的语句只需要增加新的终结符和非终结符表达式,不需要修改现有类。
  • 解释器模式的缺点
    • 对于复杂文法而言,类的数量会激增,导致系统难以维护。
    • 解释器模式递归使用,对于递归深度大的情况效率较低。

UML图

在这里插入图片描述

具体代码实现

Context 数据实体类,可以包含一些方法
package InterpreterPatternModel;

public class TestContext {
    private Integer a1;

    private Integer a2;

    private  String a3;

    public TestContext(Integer a1, Integer a2, String a3){
        this.a1 = a1;
        this.a2 = a2;
        this.a3 = a3;
    }

    public String getA3() {
        return a3;
    }

    public void setA3(String a3) {
        this.a3 = a3;
    }

    public Integer getA1() {
        return a1;
    }

    public void setA1(Integer a1) {
        this.a1 = a1;
    }

    public Integer getA2() {
        return a2;
    }

    public void setA2(Integer a2) {
        this.a2 = a2;
    }
}

Abstract Expression 创建接口方法
public interface AbstractExpression {
    Integer interpret(TestContext context);

}
Terminal Expression 对数据简单处理

Terminal Expression 是解释器模式中的一种表达式类型,它表示文法中的最基本元素,这些元素不能再进一步分解。终端表达式通常对应于文法中的终端符号,如关键字、标识符、常量等。

  • 简单性:终端表达式是最基本的表达式,它不包含其他表达式。
  • 不可分解性:终端表达式代表的是文法中最基本的符号,不能再进一步拆解。
  • 具体实现:终端表达式通常是一个具体的类,它实现了抽象表达式接口,并提供了解释自身的方法。
    使用 switch 实现 加减乘除,对数据做直接处理
package InterpreterPatternModel;

public class TestTerminalExpression implements AbstractExpression {

    @Override
    public Integer interpret(TestContext context) {
        switch (context.getA3()){
            case "+":
                return context.getA1() + context.getA2();
            case "-":
                return context.getA1() - context.getA2();
            case "*":
                return context.getA1() * context.getA2();
            case "/":
                return context.getA1() / context.getA2();
            default:
                return null;
        }
    }

}

Non-Terminal Expression 同样实现抽象接口方法

Non-Terminal Expression 也是一种表达式类型,它代表了文法中的复合元素。这些元素由一个或多个终端表达式和其他非终端表达式组成。非终端表达式定义了如何组合这些表达式来解释更复杂的句子。

  • 组合性:非终端表达式可以包含一个或多个终端表达式或其他非终端表达式。
  • 递归性:非终端表达式通常通过递归调用其他表达式的 interpret 方法来解释更复杂的表达式。
  • 具体实现:非终端表达式也是一个具体的类,它实现了抽象表达式接口,并提供了解释自身的方法。
    对数据做复杂处理以及调用上面的优化,实现再次封装
package InterpreterPatternModel;

public class TestNonTerminalExpression implements AbstractExpression {

    private TestContext context;

    public TestNonTerminalExpression(Integer a1, Integer a2, String a3){
        this.context = new TestContext(a1, a2, a3);
    }
    
    public Integer exec(){
        return this.interpret(context);
    }

    @Override
    public Integer interpret(TestContext context) {
        TestTerminalExpression testTerminalExpression = new TestTerminalExpression();
        return testTerminalExpression.interpret(context);
    }
}

Client(客户端) 调用方法
package InterpreterPatternModel;

public class TestClient {

    public static void exec(){
        TestTerminalExpression testTerminalExpression = new TestTerminalExpression();
        Integer interpret = testTerminalExpression.interpret(new TestContext(1, 2, "*"));
        System.out.println(interpret);
        TestNonTerminalExpression nonTerminal = new TestNonTerminalExpression(10, 2, "+");
        Integer exec = nonTerminal.exec();
        System.out.println(exec);
        Integer interpret1 = nonTerminal.interpret(new TestContext(new TestNonTerminalExpression(1, 2, "*").exec(), new TestNonTerminalExpression(10, 2, "-").exec(), "+"));
        System.out.println(interpret1);
    }
}

通过Terminal Expression(终端表达式) 和 Non-Terminal Expression(非终端表达式)
这两种表达式类型的组合,解释器模式能够构建出一个能够解析并解释复杂文法的解释器。这种模式使得添加新的语法规则变得相对容易,因为只需添加新的终端和非终端表达式即可。但是,随着文法复杂度的增加,非终端表达式的数量也会增加,这可能导致类的数量激增,从而增加了系统的复杂性和维护难度。

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

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

相关文章

Java 字符串、数组、ArrayList之间的相互转换

1. 数组转字符串 import java.util.Arrays;public class Test02 {public static void main(String[] args){String[] scores1 new String[]{"10","20","30","40","50"};String[] scores2 {"10","20",…

开源的 Kafka 管理平台

来源:github.com/provectus/kafka-ui Apache Kafka UI 是一个免费的开源 Web UI,用于监控和管理 Apache Kafka 集群,可方便地查看 Kafka Brokers、Topics、消息、Consumer 等情况,支持多集群管理、性能监控、访问控制等功能。 1 …

自编码器(Autoencoder,AE)

Autoencoders and their applications in machine learning: a survey 1、Autoencoder(自编码器,AE) 自编码器(Autoencoder)是一种无监督学习算法,主要用于数据的降维、特征提取和数据重建。自编码器由两个…

计算机毕业设计hadoop+spark+hive动漫推荐系统 动漫视频推荐系统 漫画分析可视化大屏 漫画爬虫 漫画推荐系统 漫画爬虫 知识图谱 大数据

《HadoopSparkHive动漫推荐系统》开题报告 一、引言 随着互联网技术的飞速发展,动漫产业的数据量急剧增长。用户面临着海量动漫作品的选择难题,如何从这些数据中高效地提取有价值的信息,为用户推荐符合其喜好的动漫作品,成为当前…

创客匠人_公域变天!知识IP传统打法失灵,不转型就出局!

“什么叫定位?我认为定位就是你在这个社会里找到属于你自己的分工。然后通过深挖客户群体的痛点,去做产品升级和迭代。企业的价值或者IP的价值,就是为这个社会解决某一方面的问题。”老蒋说。 在老蒋创客圈第65期对话标杆直播连麦中&#xff…

PTA求一批整数中出现最多的个位数字

作者 徐镜春 单位 浙江大学 给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。 输入格式: 输入在第1行中给出正整数…

鸿蒙OS Page Ability

鸿蒙OS 基本概念 Page与AbilitySlice Page 模板(以下简称“Page”)是 FA 唯一支持的模板,用于提供与用户交互的能力。一个 Page 可以由一个或多个 AbilitySlice 构成,AbilitySlice 是指应用的单个页面及其控制逻辑的总和。 当一…

虚拟现实智能家居实训系统实训解决方案

随着科技的飞速发展,智能家居已成为现代生活的重要组成部分,它不仅极大地提升了居住的便捷性与舒适度,还推动了物联网、大数据、人工智能等前沿技术的融合应用。为了满足市场对智能家居专业人才日益增长的需求,虚拟现实智能家居实…

在Go中迅速使用RabbitMQ

文章目录 1 认识1.1 MQ分类1.2 安装1.3 基本流程 2 [Work模型](https://www.rabbitmq.com/tutorials/tutorial-two-go#preparation)3 交换机3.1 fanout3.2 direct3.3 [topic](https://www.rabbitmq.com/tutorials/tutorial-five-go) 4 Golang创建交换机/队列/Publish/Consume/B…

视频监控系统选型:为何EasyCVR视频汇聚平台成为优选方案

随着科技的飞速发展,视频监控系统作为现代安防体系的核心组成部分,其重要性日益凸显。无论是智慧城市、智慧交通、智慧园区还是企业安防,高效、稳定、智能的视频监控解决方案都是不可或缺的。在众多视频监控平台中,EasyCVR视频汇聚…

《向量数据库指南》——如何评估 Embedding 模型

01. 简介 在此前发布的文章(https://zilliz.com/learn/sparse-and-dense-embeddings)中,我们探析了当前稠密 Embedding 模型的架构,并介绍了 sentence-transformers 库的一些基础用法。虽然通过 sentence-transformers 可以使用众多预训练模型,但这些模型几乎都采用了与…

【空气能热泵热水系统原理

高温直热循环系列:1、系统简图(带电辅热) 注:1)图适用于以一次加热式热泵热水机组为主机的热水系统。2)系统所有机组的启、停都由生活热水箱中水位开关控制。机组以直热式动作的条件为:①当线控器设定水箱…

VM中创建CentOS 7及VM中如何修改DHCP的IP网段

一、创建虚拟机 1新建Centos虚拟机 2类型选择 3版本兼容性选择 4镜像选择 5安装系统选择 6虚拟机的创建路径(选择C盘以外且不包含中文名称的路径) 7硬件配置选择 网络类型的选择(通常情况下选择NAT模式) 8剩下的全部按推荐走&…

AcWing算法基础课-787归并排序-Java题解

大家好,我是何未来,本篇文章给大家讲解《AcWing算法基础课》787 题——归并排序。本文详细介绍了归并排序的算法思路,包括分解、合并和递归排序三个主要步骤。通过 Java 代码实现,展示了如何将数组递归分解至单个元素,…

揭秘!焦虑症与气血不足:是巧合还是内在关联?

在这个快节奏、高压力的时代,焦虑症仿佛成了现代人难以言说的“隐形伴侣”。失眠、心悸、易怒……这些症状让许多人苦不堪言。而另一边,中医理论中的“气血不足”也常常被视为身体虚弱、情绪不稳的根源。那么,焦虑症与气血不足之间&#xff0…

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法&#xff1a…

使用Selenium与WebDriver实现跨浏览器自动化数据抓取

背景/引言 在数据驱动的时代,网络爬虫成为了收集和分析海量数据的关键工具。为了应对不同浏览器环境下的兼容性问题,Selenium与WebDriver成为了开发者实现跨浏览器自动化数据抓取的首选工具。本文将深入探讨如何利用Selenium和WebDriver实现跨浏览器的数…

客户管理太难了?你可能忽视了这些常见问题

在客户管理中,你是不是常常感到力不从心?客户信息不准确、沟通不到位、客户流失毫无预警……这些问题不仅让管理者头疼,还严重影响企业的业绩增长。客户管理看似简单,但往往隐藏着很多不易察觉的细节问题。如果你觉得客户越来越难…

什么运动耳机好用?六大技巧助力选购优质产品

​开放式蓝牙耳机现在超流行,不仅年轻人爱用,连不少上了年纪的人也喜欢在公园里散步时戴上。这些耳机无论是听歌、学习、健身还是办公,都能派上用场。到了2024年,想要挑到一款既好用又好听的开放式蓝牙耳机,得好好比较…

Vue2+JS项目升级为Vue3+TS之jquery的maphilight引入项目

本人由于想提升自己的项目开发能力,所以将就项目的vue2JavaScriptwebpack的旧技术栈升级为vue3typescriptvite的技术栈,所以遇到很多坑,以下是maphilight的解决方法。 众所周知jquery是基于JavaScript进行开发,但是已有typescript…