java设计模式(十三)解释器模式

news2024/12/27 3:36:05

目录

  • 定义
  • 模式结构
  • 角色职责
  • 代码实现
  • 场景适用
  • 优缺点

定义

解释器模式(Interpreter Pattern) 提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等,是一种类行为型模式。

模式结构

在这里插入图片描述

角色职责

1.环境角色(Context): 用来存储解释器的上下文环境,包含解释器之外的一些全局信息,比如需要解释的文法等。
2.客户端(Client): 解释器的客户端,通常在这里将按照语言的语法做的表达式转换成为使用解释器对象描述的抽象语法树,然后调用解释操作。
3.解释器抽象类(AbstractExpression): 定义解释器的接口,约定解释器的解释操作。
4.终结符表达式(TerminalExpression): 解释器具体实现类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例,通常在一个解释器模式中只有少数个终结符表达式,它们的实例可以通过非终结符表达式组成较为复杂的句子。
5.非终结符表达式(NonterminalExpression): 解释器具体实现类,它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此解释操作一般通过递归的方式来完成。

代码实现

环境角色:

public class Context {
    private String[] citys = {"韶关", "广州"};
    private String[] persons = {"老人", "妇女", "儿童"};
    private Expression cityPerson;
    public Context() {
        Expression city = new TerminalExpression(citys);
        Expression person = new TerminalExpression(persons);
        cityPerson = new AndExpression(city, person);
    }
    public void freeRide(String info) {
        boolean ok = cityPerson.interpret(info);
        if (ok) System.out.println("您是" + info + ",您本次乘车免费!");
        else System.out.println(info + ",您不是免费人员,本次乘车扣费2元!");
    }
}

解释器抽象类:

// 抽象表达式类
public interface Expression {
    public boolean interpret(String info);    //解释方法
}

终结表达式:

public class TerminalExpression implements Expression {
    private Set<String> set = new HashSet<String>();
    public TerminalExpression(String[] data) {
        for (int i = 0; i < data.length; i++) set.add(data[i]);
    }
    public boolean interpret(String info) {
        if (set.contains(info)) {
            return true;
        }
        return false;
    }
}

非终结表达式:

public class AndExpression implements Expression {
    private Expression city = null;
    private Expression person = null;
    public AndExpression(Expression city, Expression person) {
        this.city = city;
        this.person = person;
    }
    public boolean interpret(String info) {
        String s[] = info.split("的");
        return city.interpret(s[0]) && person.interpret(s[1]);
    }
}

客户端:

public class InterpreterPattern {
    public static void main(String[] args) {
        Context bus = new Context();
        bus.freeRide("韶关的老人");
        bus.freeRide("韶关的年轻人");
        bus.freeRide("广州的妇女");
        bus.freeRide("广州的儿童");
        bus.freeRide("山东的儿童");
    }
}

打印结果:

您是韶关的老人,您本次乘车免费!
韶关的年轻人,您不是免费人员,本次乘车扣费2元!
您是广州的妇女,您本次乘车免费!
您是广州的儿童,您本次乘车免费!
山东的儿童,您不是免费人员,本次乘车扣费2元!

场景适用

1.可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
2.一些重复出现的问题可以用一种点单的语言来进行表达。
3.文法较为简单,对于复杂的文法,解释器模式中的文法类层次结构将变得很庞大而无法管理,此时最好使用语法分析程序生成器。
4.效率不是关键问题,最高效的解释器通常不是通过直接解释语法分析树来实现的,而是需要将它们转换成另一种形式,使用解释器模式的执行效率并不高。

优缺点

优点:
1.易于改变和扩展文法,由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承机制来改变和扩展文法,实现简单语言方便。
2.易于实现文法,在抽象语法树中每一个节点类的实现方式都是相似的,这些类的编写都不是很复杂,它们还可以通过一些工具自动生成。
3.增加了新的解释表达式的方式,解释器模式可以让用户较为方便的增加新类型的表达式,增加新的表达式时无需对现有的表达式进行修改,符合开闭原则。

缺点:
1.对于复杂文法难以维护,在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,则可能难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。
2.执行效率较低,由于解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢。
3.应用场景很有限,在软件开发中很少需要自定义文法规则,因此该模式的使用频率很低,在一班的软件中难以找到其应用实例,导致理解和使用该模式的难度较大。
在这里插入图片描述

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

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

相关文章

Linux 内存管理6——slab内存池的创建初始化过程

在上篇文章 中&#xff0c;笔者带大家从一个最简单的物理内存页开始&#xff0c;一步一步演进 slab cache 的架构&#xff0c;最终得到了一副 slab cache 完整的架构图&#xff1a; 在本文的内容中&#xff0c;笔者会带大家到内核源码实现中&#xff0c;来看一下 slab cache 在…

第三章:基本的SELECT语句

第三章&#xff1a;基本的SELECT语句 3.1&#xff1a;SQL概述 SQL背景知识 1946年&#xff0c;世界上第一台电脑诞生&#xff0c;如今&#xff0c;借由这台电脑发展起来的互联网已经自成江湖。在这几十年里&#xff0c;无数的技术、产业在这片江湖里沉浮&#xff0c;有的方兴未…

HTTP和HTTPS

目录 HTTP 告知服务器意图的HTTP方法 状态码告知从服务器端返回的请求结果 2XX 成功 3XX 重定向 4XX客户端错误 5XX服务器错误 使用Cookie的状态管理 HTTP 的缺点 HTTPS HTTP 当我们在网页浏览器的地址栏输入URL时&#xff0c;Web页面是如何呈现的吗&#xff1f; …

Linux 面试题-(腾讯,百度,美团,滴滴)

Linux 面试题-(腾讯,百度,美团,滴滴) 分析日志t.log(访问量)&#xff0c;将各个ip 地址截取&#xff0c;并统计出现次数,并按从大到小排序(腾讯) http://192.168.200.10/index1.html http://192.168.200.10/index2.html http://192.168.200.20/index1.html http://192.168.20…

Python 类和对象

一、什么是类和对象 Python和Java一样&#xff0c;都是面向对象的编程语言&#xff0c;面向对象编程其实是一种封装代码的方法&#xff0c;把一些公共的属性或者方法封装到一个类中&#xff0c;然后再通过这个类可以创建多个对象&#xff0c;最后使用这些对象去调用这些封装起…

【教程】两种免费更新iOS17测试版的方法

苹果iOS17系统已经发布&#xff0c;目前所有用户都可以免费注册成为开发者&#xff0c;升级iOS17开发者测试版 注意&#xff0c;现在不是通过描述文件来更新系统了&#xff0c;给大家带来两种更新升级方法&#xff0c;看下文操作 方法一 苹果官网注册 按照下图发消息“更新” …

java设计模式(十六)命令模式

目录 定义模式结构角色职责代码实现适用场景优缺点 定义 命令模式&#xff08;Command Pattern&#xff09; 又叫动作模式或事务模式。指的是将一个请求封装成一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开&#xff0c;然后可以使用不同的请求把客户端参数化&a…

数据库篇——锁

目录 引文A——活锁 引文B——死锁 1、表锁 1.1 关于 S 锁 1.2 关于 X 锁 1.3 关于意向锁 2、行锁 2.1 关于记录锁 2.2 关于间隙锁 2.3 关于临键锁 2.4 关于插入意向锁 3、页锁 我们在谈表锁、行锁以及页锁之前&#xff0c;先聊一聊 活锁&#x1f512;与 死锁&#x1f512;的…

RabbitMQ安装、端口修改、简单的角色介绍

前提 本文介绍RabbitMQ安装的环境是CentOS7版本的Linux云服务器。 官网&#xff1a;https://www.rabbitmq.com/ RabbitMQ的安装 由于RabbitMQ是使用Erlang语言开发的&#xff0c;所以我们在安装RabbitMQ之前需要在服务器中安装Erlang语言的环境。在Linux中执行下面命令&…

Day_43插入排序

目录 一. 关于插入排序 1. 排序的定义 2. 插入排序 二. 插入排序的实现过程 三. 代码实现过程 1. 插入排序核心代码 四. 代码展示 五. 数据测试 六. 总结 一. 关于插入排序 1. 排序的定义 排序&#xff0c;就是重新排列表中的元素&#xff0c;使表中的元素满足按关键字有序…

AIGC与AidLux互联应用——AidLux端AIGC测评(二)PC端云端Stable Diffusion模型推理应用(文生图,图生图)

在这里插入图片描述 Stable Diffusion模型搭建首先下载diffusers&#xff0c;然后安装&#xff0c;命令如下&#xff1a; git clone https://github.com/huggingface/diffusers.git pip install diffusers cd diffusers pip install . ubuntu和win系统下都可以 文生图&#x…

React Hooks 组件化开发(常用)

本文章视频地址&#xff1a;视频链接 一、React组件分类 二、Hook函数概览 Hook 是 React 16.8 的新增特性&#xff01;并且只能运用到函数组件中&#xff01; 1.useState 作用&#xff1a;在函数组件中使用状态&#xff0c;修改状态值可让函数组件更新&#xff0c;类似于类…

鸿蒙初识

学习官网&#xff1a;https://www.harmonyos.com/cn/develop 准备 注册&#xff0c;安装软件(node:12, DevEco Studio)&#xff1a; 在实际开发中node最好使用nvm进行版本管理。 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-00000010…

ChatGPT-Plugins-Searchable

ChatGPT Plus 用户应该都知道Plus已经开放了插件功能&#xff0c;但是在插件商店里存在一个较大的问题插件数量超过100款&#xff0c;却没有便捷的搜索功能。 而我们在查找一款插件时&#xff0c;需要从插件商店的第一页点击到最后一页一个个找&#xff0c;显然这非常的麻烦。 …

驱动开发--驱动模块

目录 1.驱动模块 hello.c Makefile 2.内核中的打印函数&#xff08;编写第一个驱动程序&#xff09; Source Insight 使用&#xff1a; 3.打印函数编写 分析 4、驱动的多文件编译 5、模块传递参数 6、安装好驱动之后如何传参&#xff1f; 7、字符设备驱动 8、字符设…

chatgpt赋能python:Python如何突破VIP限制

Python如何突破VIP限制 在这个数字内容时代&#xff0c;我们经常使用各种网站和应用程序来获取视频、音乐、软件等数字资源。但是&#xff0c;某些资源可能受到VIP限制&#xff0c;这意味着我们需要付费才能获得完整的访问权限。但是&#xff0c;如果你了解Python编程&#xf…

Agile | 聊聊敏捷开发

什么是敏捷开发 敏捷开发是一种迭代和增量的项目管理方法&#xff0c;优先考虑适应性、协作和快速交付&#xff0c;而不是遵循严格的计划[0]。它是在《敏捷软件开发宣言》和《12项原则》中表达的一组价值观和原则[1]。敏捷是基于这些价值观和原则的一组框架和实践的总称。敏捷…

【数据库】修改数据库密码及端口

一、修改MySQL配置文件 想要在没有密码的状态下修改MySQL的密码&#xff0c;必须跳过MySQL登录时的登录密码权限的验证&#xff0c;取消掉这个验证的方式如下&#xff1a; 1、找到MySQL的安装文件中的my.ini文件 一般人应该能找到的吧&#xff0c;配置MySQL的环境变量中也有安…

关于数据中心机房动环监控系统的应用与设计 安科瑞 许敏

摘 要&#xff1a; 机房动力和环境监控系统是对分布的精密机房及通信局&#xff08;站&#xff09;内的电源、空调、油机、蓄电池、高低压配电等多种设备和环境的各种参数、图像、声音等进行遥测、并对设备进行集中监控、集中维护和集中管理&#xff0c;是现代化机房管理手段和…

【Leetcode -138.复制带随机指针的链表 -2130.链表最大孪生和】

Leetcode Leetcode -138.复制带随机指针的链表Leetcode -2130.链表最大孪生和 Leetcode -138.复制带随机指针的链表 题目&#xff1a;给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;该指针可以指向链表中的任何节点或空节点。 构…