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

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

文章目录

    • 解释器模式简绍
    • 解释器模式的结构
    • 优缺点
    • 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 {@Overridepublic 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);}@Overridepublic 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(非终端表达式)
这两种表达式类型的组合,解释器模式能够构建出一个能够解析并解释复杂文法的解释器。这种模式使得添加新的语法规则变得相对容易,因为只需添加新的终端和非终端表达式即可。但是,随着文法复杂度的增加,非终端表达式的数量也会增加,这可能导致类的数量激增,从而增加了系统的复杂性和维护难度。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • spark任务优化参数整理
  • Linux 之 RPM [Red - Hat Package Manager]【包管理】
  • [数据集][目标检测]肺炎检测数据集VOC+YOLO格式4983张2类别
  • Java设计模式中工厂模式与策略模式的区别
  • 提升效率必备,掌握这些Shell文本处理技能!
  • 虚拟机安装VMware-tools详细教程
  • 基于java+springboot+vue实现的林业产品推荐系统(文末源码+Lw)135
  • 如何把大的txt文件拆分为小的文件?
  • 正版软件 | Sticky Password 终身密码管理器 - 使用教程分享
  • 关于linux里的df命令以及inode、数据块-stat链接数以及关于awk文本处理命令中内置函数sub、gsub、sprintf
  • 如何打造一款成功的游戏
  • 通用四期ARM架构银河麒麟桌面操作系统V10【安装、配置FTP客户端】
  • 小红书为什么起号失败?
  • 【中间件】-容器编排平台Kubernetes简介
  • Vue邮件发送:如何有效集成邮件发送功能?
  • HTML中设置input等文本框为不可操作
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • PHP面试之三:MySQL数据库
  • use Google search engine
  • vue学习系列(二)vue-cli
  • 百度地图API标注+时间轴组件
  • 如何设计一个微型分布式架构?
  • 如何用纯 CSS 创作一个货车 loader
  • ###C语言程序设计-----C语言学习(6)#
  • #if 1...#endif
  • (ZT)出版业改革:该死的死,该生的生
  • (二十三)Flask之高频面试点
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (七)glDrawArry绘制
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .net 微服务 服务保护 自动重试 Polly
  • .Net6使用WebSocket与前端进行通信
  • .Net转前端开发-启航篇,如何定制博客园主题
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • @RequestParam详解
  • @selector(..)警告提示
  • [16/N]论得趣
  • [AIGC] HashMap的扩容与缩容:动态调整容量以提高性能
  • [Algorithm][综合训练][拜访][买卖股票的最好时机(四)]详细讲解
  • [BZOJ 2142]礼物(扩展Lucas定理)
  • [bzoj4010][HNOI2015]菜肴制作_贪心_拓扑排序
  • [C++] 容器适配器:深入理解Stack与Queue的底层原理
  • [C语言]——内存函数
  • [Day 8] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
  • [FTP]pureftp部署和优化
  • [HNOI2008]水平可见直线
  • [iOS]内存分区
  • [iphone-cocos2d]关于Loading的若干处理和讨论
  • [Java、Android面试]_10_Java中==与equal()方法的区别?重写equal()方法?
  • [JAVA]初识线程池及其基本应用
  • [JS]数据类型