【行为型模式】解释器模式

一、解释器模式概述

        解释器模式定义给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。也就是说,用编译语言的方式来分析应用中的实例。这种模式实现了文法表达式处理的接口,该接口解释一个特定的上下文。(类行为型)

  • 解释器模式的优缺点
    • 优点
      • 1.将每一个语法规则表示成一个类,方便于实现语言;
      • 2.因为语法由许多类表示,所以你可以轻易地改变或扩展此语言;
      • 3.通过在类结构中加入新的方法,可以在解释的同时增加新的行为,例如打印格式的美化或者进行复杂的程序验证。
    • 缺点
      • 当语法规则的数目太大时,这个模式可能会变得非常繁杂。在这种情况下,使用解析器/编译器的产生器可能更合适。
  • 适用场景
    • 1.当你需要实现一个简单的语言时,使用解释器;
    • 2.当你有一个简单的语法,而且简单比效率更重要时,使用解释器;
    • 3.可以处理脚本语言和编程语言。

解释器模式与适配器模式这两个模式类似 , 但是略有不同:

  • 适配器模式 : 不需要预先知道适配器的规则;
  • 解释器模式 : 需要预先将规则写好 , 根据规则执行解释。

二、代码实现

        解释器模式主要角色如下:

  • 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  • 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  • 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  • 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。
  • 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

用解释器模式设计一个“韶粵通”公交车卡的读卡器程序。

说明:假如“韶粵通”公交车读卡器可以判断乘客的身份,如果是“韶关”或者“广州”的“老人” “妇女”“儿童”就可以免费乘车,其他人员乘车一次扣 2 元。

文法规则如下:
<expression> ::= <city>的<person>
<city> ::= 韶关|广州
<person> ::= 老人|妇女|儿童
        2.1 抽象表达式(IExpression)
package interpreter.buscard;
//抽象表达式类
public interface IExpression{public boolean interpret(String info);
}
        2.2 终结符表达式(TerminalExp)
package interpreter.buscard;
import java.util.HashSet;
import java.util.Set;
//终结符表达式类
public class TerminalExp implements IExpression {private Set<String> set = new HashSet<>();public TerminalExp(String[] data) {for (int i = 0; i < data.length; i++){set.add(data[i]);}}@Overridepublic boolean interpret(String info) {// TODO Auto-generated method stubif (set.contains(info)){return true;}return false;}}
        2.3 非终结符表达式(AndExpression)
package interpreter.buscard;
//非终结符表达式类
public class AndExpression implements IExpression {private IExpression city = null;private IExpression person = null;public AndExpression(IExpression city, IExpression person) {this.city = city;this.person = person;}@Overridepublic boolean interpret(String info) {// TODO Auto-generated method stubString[] s = info.split("的");return city.interpret(s[0]) && person.interpret(s[1]);}}
        2.4 环境(context)
package interpreter.buscard;
//环境类
public class Context {private String[] cities = {"韶关","广州"};private String[] persons = {"老人","妇女","儿童"};private IExpression cityPerson;public Context() {IExpression city = new TerminalExp(cities);IExpression person = new TerminalExp(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元!");}}
}
        2.5 客户端(Test)
package interpreter.buscard;public class Test {public static void main(String[] args) {// TODO Auto-generated method stubContext bus = new Context();bus.freeRide("韶关的老人");bus.freeRide("韶关的年轻人");bus.freeRide("广州的妇女");bus.freeRide("广州的儿童");bus.freeRide("山东的儿童");}}
        2.6 UML图

三、代码结构图

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

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

相关文章

贪吃蛇项目实战——学习详解

前言:贪吃蛇是一个经典的游戏&#xff0c; 本节将使用c语言实现一个简易的的贪吃蛇小游戏。 本节内容适合已经学完c语言还有数据结构链表的友友们。 我们要实现的贪吃蛇是在控制台进行游戏的。 它运行起来是这样的&#xff1a; 贪吃蛇 那么&#xff0c; 为了实现这个小游戏。 我…

Spring-IOC之组件扫描

版本 Spring Framework 6.0.9​ 1. 前言 通过自动扫描&#xff0c;Spring 会自动从扫描指定的包及其子包下的所有类&#xff0c;并根据类上的特定注解将该类装配到容器中&#xff0c;而无需在 XML 配置文件或 Java 配置类中逐一声明每一个 Bean。 支持的注解 Spring 支持一系…

C++/BOOST filesystem fs::directory_iterator一个滑稽的错误

错误来源于&#xff0c;用 fs::directory_iterator iter(folderPath), end; 然后for循环 for (; iter ! iter_end; iter) {} 最开始没问题&#xff0c;后来说加个进度条&#xff0c;统计一下所有文件数量&#xff0c;用了std::distance&#xff0c; int totalFiles std::…

android系统更新ActivityManager中APi问题解决

遇到在alps/frameworks/base/core/java/android/app/ActivityManager.java 进行了新接口的增加时&#xff0c;需要进行更新api操作以刷新以下两文件。 alps/frameworks/base/core/api/system-current.txt alps/frameworks/base/core/api/system-lint-baseline.txt 否则会报错…

C++从零开始websevere服务器从搭建到上线|使用华为云服务器进行项目部署

文章目录 公网IP和私有IP地址公网IP私有IP地址为什么我们需要两个IP地址呢 云服务器设置防火墙配置基础配置云服务器防火墙配置云服务器安全组 总结 问题背景 关于使用华为云服务器进行项目部署&#xff0c;25届C秋招选手&#xff0c;刚写完一个websever项目&#xff0c;想着部…

8. 中断下半页 与 延迟处理

目录 中断下半页 软中断 Tasklet Work Queues 回顾一下 Reference (偷个懒&#xff1a;这里不将怎么用hhh) 我们现在开始考虑中断的部分了。我们直到处理设备&#xff08;不管是CPU自己的还是外部设备的&#xff09;的中断是操作系统的一个重要任务。 我们说中断是异步的…

柱状图展示异步统计数据

PC端 APP端 Controller层 package com.cnpc.dj.party.controller;import com.alibaba.fastjson.JSONObject; import com.cnpc.dj.common.JsonResult; import com.cnpc.dj.common.context.BaseContextHandler; import com.cnpc.dj.common.utils.DateUtils; import com.cnpc.dj.…

js的算法-交换排序(快速排序)

快速排序 基本思想 快速排序的基本思想是基于分治法的&#xff1a;在待排序表L【1...n】中任意取一个元素p 作为枢轴&#xff08;或基准&#xff0c;通常取首元素&#xff09;。通过一趟排序将待排序表划分为独立的两部分L【1...k-1】和L【k1...n】;这样的话&#xff0c;L【1…

【视觉论文】VIT - Vision Transformers

论文&#xff1a;AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE 链接&#xff1a;https://arxiv.org/abs/2010.11929 很多人博主都写烂了的论文&#xff0c;我到现在才真正翻开论文看&#xff0c;21年的工作&#xff0c;正好是刚毕业那年&…

分析 MyBatis/MyBatis-Plus 慢 SQL 的分析组件 --SQL 慢镜️‍♀️

大家好&#xff01;我是聪ζ&#x1f331;我做了一个分析 MyBatis/MyBatis-Plus 慢 SQL 的分析组件 --SQL 慢镜&#x1f575;️‍♀️ GitHub仓库地址&#x1f680;: https://github.com/lhccong/sql-slow-mirror 点点 star 我的朋友们✨ 背景&#x1f9ca;&#xff1a; 大家…

使用autocannon和0x对网站进行性能分析(node)

npm i autocannon -g autocannon -c 100 -d 5 -p 10 http://localhost:3000/ 0x -o app.js 火焰图是根据程序的栈的状态对出现函数的采样数据统计而得&#xff0c;宽度代表函数运行一次所需的时长、高度代表栈的层数、颜色深度代表函数在采样中出现的频率&#xff0c;因此宽度…

Python-GEE遥感云大数据分析、管理与可视化

原文链接&#xff1a;Python-GEE遥感云大数据分析、管理与可视化https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247601238&idx2&sn6b0557cf61451eaff65f025d648da869&chksmfa820db1cdf584a76de953b96519704177e6206d4ecd47a2f2fabbcac2f7ea619b0bce184…