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

设计模式行为型——解释器模式

目录

什么是解释器模式

解释器模式的实现

解释器模式角色

解释器模式类图

解释器模式举例

解释器模式代码实现

解释器模式的特点

优点

缺点

使用场景

注意事项

实际应用


什么是解释器模式

        解释器模式(Interpreter Pattern)属于行为型模式,其提供了评估语言的语法或表达式的方式。给定一个语言,解释器模式可以定义出其文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。解释器中涉及到的文法,就是符合一定规则的语句结构.其实质是把语言中的每个符号定义成一个(对象)类,从而把每个程序转换成一个具体的对象树。

解释器模式的实现

解释器模式角色

环境角色(Context):用来存储解释器的上下文环境,包含解释器之外的一些全局信息,比如需要解释的文法等。
解释器抽象类角色(Abstract Expression):定义解释器的接口,声明一个所有的具体表达式角色都需要实现的抽象接口,约定解释器的解释操作。
终结符表达式角色(Terminal Expression):解释器具体实现类,实现了抽象表达式角色所要求的接口,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。通常在一个解释器模式中只有少数个终结符表达式,其实例可以通过非终结符表达式组成较为复杂的句子。
非终结符表达式角色(Nonterminal Expression):解释器具体实现类,,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。其非终结符表达式中即可包含终结符表达式,也可继续包含非终结符表达式,因此解释操作一般通过递归的方式来完成。

解释器模式类图

解释器模式举例

        比如我们要定义一个“+”,“-”的操作,通过表达式角色中的解释器来完事具体的加减操作。

解释器模式代码实现

环境角色

package com.common.demo.pattern.interpreter;import java.util.HashMap;
import java.util.Map;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 环境角色* @date 2023/08/02 21:20:30*/
public class Context {//存储变量及对应的值private Map<VariableExpression,Integer> map = new HashMap<>();//添加变量public void addVar(VariableExpression variable, Integer value){map.put(variable,value);}//根据变量获取对应的值public int getValue(VariableExpression variable){return map.get(variable);}
}

解释器抽象角色

package com.common.demo.pattern.interpreter;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 抽象表达式* @date 2023/08/02 21:28:04*/
public interface Expression {int interpret(Context context);
}

终结表达式角色

package com.common.demo.pattern.interpreter;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 终结表达式角色:加减的数据变量* @date 2023/08/02 21:30:06*/
public class VariableExpression implements Expression {/*** 声明存储的变量名*/private String name;public VariableExpression(String name) {this.name = name;}@Overridepublic int interpret(Context context) {return context.getValue(this);}@Overridepublic String toString() {return name;}
}

非终结表达式角色

package com.common.demo.pattern.interpreter;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 非终结表达式角色:减法* @date 2023/08/02 21:33:49*/
public class MinusExpression implements Expression{//左边表达式 变量private Expression left;//右边表达式 变量private Expression right;public MinusExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {//返回左边的值 - 右边的值return left.interpret(context)-right.interpret(context);}
}
package com.common.demo.pattern.interpreter;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc 非终结表达式角色:加法* @date 2023/08/02 21:33:00*/
public class PlusExpression implements Expression {//左边表达式 变量private Expression left;//右边表达式 变量private Expression right;public PlusExpression(Expression left, Expression right) {this.left = left;this.right = right;}@Overridepublic int interpret(Context context) {//返回左边的值 + 右边的值return left.interpret(context) + right.interpret(context);}
}

测试代码

package com.common.demo.pattern.interpreter;/*** @author Evan Walker 昂焱数据: https://www.ayshuju.com* @version 1.0* @desc* @date 2023/08/02 21:35:29*/
public class ClientTest {public static void main(String[] args) {//定义环境类Context context = new Context();//定义变量VariableExpression a = new VariableExpression("a");VariableExpression b = new VariableExpression("b");VariableExpression c = new VariableExpression("c");//将变量添加到环境类context.addVar(a,13);context.addVar(b,2);context.addVar(c,3);//运算   a+b-c  即13+2-3Expression expression = new PlusExpression(a,new MinusExpression(b,c));//结果int res = expression.interpret(context);System.out.println("结果为:"+res);}
}

测试截图

解释器模式的特点

优点

  1. 可扩展性强:可以通过扩展语言中的表达式和语法规则来实现新的行为,可以通过继承机制来改变和扩展文法。
  2. 易于实现文法:解释器模式实现相对简单,只需要实现抽象表达式和具体表达式类即可,而定义抽象语法树中各个节点地类的实现大体类似。
  3. 易于拓展语法规则:解释器模式可以让用户较为方便的增加新类型的表达式,增加新的表达式时无需对现有的表达式进行修改,符合开闭原则。

缺点

  1. 执行效率较低:解释器模式中通常使用大量的循环和递归调用,当要解释的句子较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  2. 会引起类膨胀:解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
  3. 可应用的场景比较少:在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。
  4. 复杂的文法比较难维护:对于复杂文法难以维护,其每一条规则至少需要定义一个类,若一个语言包含太多文法规则,则可能难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。

使用场景

  1. 当语言的文法较为简单,且执行效率、性能要求不高。
  2. 当问题重复出现,相似的处理逻辑,可抽象为一种简单语言,且可以用一种简单的语言来进行表达时。
  3. 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如XML文档解释。

注意事项

  1. 尽量不要在重要的模块中使用解释器模式,否则维护会是一个很大的问题。在项目中可以使用shell,JRuby,Groovy等脚本语言来代替解释器模式,弥补Java编译型语言的不足。
  2. 对执行效率、性能要求时,不要使用解释器模式
  3. 复杂的文法,解释器模式中的文法类层次结构将变得很庞大而无法管理,此时最好使用语法分析程序生成器。

实际应用

  1. mysql中的sql语句解析。
  2. JDK中Pattern对正则表达式的编译和解析。
  3. Spring中ExpressionParser接口的使用。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

相关文章:

设计模式行为型——解释器模式

目录 什么是解释器模式 解释器模式的实现 解释器模式角色 解释器模式类图 解释器模式举例 解释器模式代码实现 解释器模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是解释器模式 解释器模式&#xff08;Interpreter Pattern&#xff09;属于行为型模式&…...

使用 Webpack 优化前端开发流程

在现代前端开发中&#xff0c;构建工具的选择和优化流程的设计至关重要。Webpack 是一个功能强大的前端构建工具&#xff0c;能够优化我们的开发流程&#xff0c;提高开发效率和项目性能。本文将介绍如何使用 Webpack 来优化前端开发流程。 代码优化和资源管理也是前端项目中不…...

mysql的分库分表脚本

目录 一.分库分表优点二.过程思路脚本实现验证 一.分库分表优点 1&#xff0c;提高系统的可扩展性和性能&#xff1a;通过分库分表&#xff0c;可以将数据分布在多个节点上&#xff0c;从而提高系统的负载能力和处理性能。 2&#xff0c;精确备份和恢复&#xff1a;分库分表备…...

JavaEE初阶之文件操作 —— IO

目录 一、认识文件 1.1认识文件 1.2树型结构组织 和 目录 1.3文件路径(Path) 1.4其他知识 二、Java 中操作文件 2.1File 概述 2.2代码示例 三、文件内容的读写 —— 数据流 3.1InputStream 概述 ​3.2FileInputStream 概述 3.3代码示例 3.4利用 Scanner 进行字…...

客户端代码 VS 服务端代码 简述

客户端代码和服务端代码是计算机网络交互中的两种重要代码类型。在计算机网络中&#xff0c;客户端和服务器是一对设备模型&#xff0c;客户端&#xff08;Client&#xff09;负责向服务器发送请求&#xff0c;服务器&#xff08;Server&#xff09;负责处理请求并返回给客户端…...

【娱乐圈明星知识图谱2】信息抽取

目录 1. 项目介绍 2. 信息抽取介绍 3. ChatGPT 信息抽取代码实战 4. 信息抽取主逻辑 5. 项目源码 1. 项目介绍 利用爬虫项目中爬取的大量信息 【娱乐圈明星知识图谱1】百科爬虫_Encarta1993的博客-CSDN博客娱乐圈明星知识图谱百度百科爬虫百度百科爬虫百度百科爬虫百度百…...

C++ rand的用法

C rand的用法 rand()介绍srand()介绍产生随机数的用法产生一定范围随机数的通用表示公式 我们知道 rand() 函数可以用来产生随机数&#xff0c;但是这不是真正意义上的随机数&#xff0c;是一个伪随机数&#xff0c;是根据一个数&#xff08;我们可以称它为种子&#xff09;为基…...

element时间选择器的默认值

概览&#xff1a;vue使用element组件&#xff0c;需要给时间选择器设置默认值&#xff0c;场景一&#xff1a;默认时间选择器&#xff0c;场景二&#xff1a;时间范围选择器&#xff0c;开始时间和结束时间。 一、默认时间选择器 实现思路&#xff1a; element组件的v-model绑…...

fiddler过滤器

1、fiddler Fiddler是一个免费、强大、跨平台的HTTP抓包工具。下载地址 2、为什么适用过滤器 不适用过滤器时&#xff0c;所有的报文都会被抓包。 我们在开发或测试时&#xff0c;只需要抓包某个域名下的报文 &#xff0c;以“www.baidu.com”为例&#xff0c;不设置过滤器&…...

面试必考精华版Leetcode2130.链表最大孪生和

题目&#xff1a; 代码&#xff08;首刷看解析 day22&#xff09;&#xff1a; class Solution { public:int pairSum(ListNode* head) {ListNode* slowhead;ListNode* fasthead->next;while(fast->next!nullptr){slowslow->next;fastfast->next->next;}//反转…...

qemu kvm 新建虚拟机

开始菜单打开虚拟机管理器...

Charles抓包工具使用(一)(macOS)

Fiddler抓包 | 竟然有这些骚操作&#xff0c;太神奇了&#xff1f; Fiddler响应拦截数据篡改&#xff0c;实现特殊场景深度测试&#xff08;一&#xff09; 利用Fiddler抓包调试工具&#xff0c;实现mock数据特殊场景深度测试&#xff08;二&#xff09; 利用Fiddler抓包调试工…...

2023年8月美团外卖3-18元红包优惠券天天领取活动日历及美团外卖红包领取使用

2023年8月美团外卖3-18元红包天天领取活动日历 根据上图美团外卖红包领取活动时间表以下时间可以天天领取3-18元美团外卖红包优惠券&#xff1a; 1、2023年8月18日 可领取美团外卖18元神券节红包&#xff1b; 2、2023年8月每周六、周日每天可领取12元美团外卖节红包&#xff…...

深度学习各层负责什么内容?

1、深度学习——神经网络简介 深度学习(Deep Learning)(也称为深度结构学习【Deep Structured Learning】、层次学习【Hierarchical Learning】或者是深度机器学习【Deep Machine Learning】)是一类算法集合&#xff0c;是机器学习的一个分支。 深度学习方法近年来&#xff0c…...

【硬件设计】模拟电子基础二--放大电路

模拟电子基础二--放大电路 一、基本放大电路1.1 初始电路1.2 静态工作点1.3 分压偏置电路 二、负反馈放大电路三、直流稳压电路 前言&#xff1a;本章为知识的简单复习&#xff0c;适合于硬件设计学习前的知识回顾&#xff0c;不适合运用于考试。 一、基本放大电路 1.1 初始电…...

基于应用值迭代的马尔可夫决策过程(MDP)的策略的机器人研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

控件旋转90度,并跟随大小缩放

控件旋转角度&#xff0c;并跟随缩放改变大小 背景使用控件结果 背景 一个项目需求&#xff0c;需要旋转某个控件90使用&#xff0c;在网上找了很多资料&#xff0c;没有特别合适的&#xff0c;自己试水试了一天半&#xff0c;终于弄了个大概其&#xff0c;特此记录 使用控件…...

软件外包开发的PHP开发框架

PHP有许多流行的开发框架&#xff0c;每个框架都有其独特的特点和优势。下面列举的只是一部分PHP开发框架&#xff0c;还有其他一些框架如Slim、Zend Framework等也值得一提。选择合适的框架取决于项目的需求和开发团队的偏好&#xff0c;您可以根据项目规模、复杂性和功能需求…...

D2L学习记录-10-词嵌入word2vec

NLP-1-词嵌入(word2vec) 参考: 《动手学深度学习 Pytorch 第1版》第10章 自然语言处理 第1、2、3 和 4节 (词嵌入) 词嵌入 (word2vec)&#xff1a; 词向量&#xff1a;自然语言中&#xff0c;词是表义的基本单元。词向量是用来表示词的向量。词嵌入 (word embedding)&#x…...

海外独立站怎么搭建?7个海外独立站搭建指南

在海外搭建独立站&#xff08;独立网站&#xff09;有几个关键步骤&#xff0c;以下是一个简要的指南&#xff1a; 选择域名和主机&#xff1a; 首先&#xff0c;选择一个适合你网站主题的域名。确保它简洁、易记&#xff0c;并且与你的品牌或内容相关联。 然后&#xff0c;…...

flask中实现restful-api

flask中实现restful-api 举例&#xff0c;我们可以创建一个用于管理任务&#xff08;Task&#xff09;的API。在这个例子中&#xff0c;我们将有以下API&#xff1a; GET /tasks: 获取所有任务POST /tasks: 创建一个新的任务GET /tasks/<id>: 获取一个任务的详情PUT /t…...

Centos7 安装man中文版手册

查找man中文安装包&#xff1a; yum search man-pages 安装man-pages-zh-CN.noarch: yum install -y man-pages-zh-CN.noarch...

untiy代码打压缩包,可设置密码

1、简单介绍&#xff1a; 用的是一个插件SharpZipLib&#xff0c;在vs的Nuget下载&#xff0c;也可以去github下载https://github.com/icsharpcode/SharpZipLib 用这个最主要的是因为&#xff0c;这个不用请求windows的文件读写权限&#xff0c;关于这个权限我搞了好久&#…...

【iOS】—— UIKit相关问题

文章目录 UIKit常用的UIKit组件懒加载的优势 CALayer和UIView区别关系 UITableViewUITableView遵循的两个delegate以及必须实现的方法上述四个必须实现方法执行顺序其他方法的执行顺序&#xff1a; UICollectionView和UITableView的区别UICollectionViewFlowLayout和UICollecti…...

Linux系统防火墙Firewalld

目录 Firewalld概述 Firewalld和iptables的区别 Firewalld网络区域 区域介绍与概念 9个预定义区域 Firewalld数据处理流程 firewalld检查数据包的源地址的规则 Firewalld防火墙的配置方式 常用的firewall-cmd命令选项 服务管理 端口管理 Firewalld概述 Firewalld防火…...

STM3232 GPIO的配置寄存器(为了移植IIC)

参考 https://blog.csdn.net/qq_45539458/article/details/129481019 https://blog.csdn.net/weixin_43314829/article/details/125573448?spm1001.2014.3001.5502 https://blog.csdn.net/m0_71548440/article/details/125894236?spm1001.2014.3001.5502 正点原子mini板 stm…...

K8s的详细介绍

1.编写yaml文件的方式 2.yaml里面的内容介绍 Pod实现机制&#xff1a;&#xff08;1&#xff09;共享网络&#xff08;2&#xff09;共享存储 共享网络:通过Pause容器&#xff0c;把其他业务容器加入到Pause容器里面&#xff0c;让所有业务容器在同一个名称空间中&#xff0c;…...

JavaWeb(8)——前端综合案例2(节流和防抖)

目录 一、节流和防抖概念 &#x1f680; 二、实例演示 &#x1f498; 三、需要注意的 &#x1f4e1; 一、节流和防抖概念 &#x1f680; 二、实例演示 &#x1f498; Lodash 简介 | Lodash中文文档 | Lodash中文网 (lodashjs.com) <!DOCTYPE html> <html lang&q…...

Spring优雅的在事务提交/回滚前后插入业务逻辑

业务背景 业务那边想要统计下我们这边每天注册商户成功和失败的数量&#xff0c;你看看怎么给他弄下这个功能 功能实现 TransactionSynchronizationManager.registerSynchronization&#xff0c;发现这是spring事务提供的注册回调接口的方法。 在事务注解方法中&#xff0c…...

day48-ajax+SSM分页

AjaxSSM分页 非分页版controller及html&#xff1a; 分页模糊查询controller&#xff1a; Postman测试&#xff08;无网页&#xff09;&#xff1a; 分页网页&#xff1a; 分页网页中添加模糊查询&#xff1a; 分页网页中实现添加功能&#xff1a; &#xff08;1&am…...