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

设计模式 解释器模式(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 {

    @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.kler.cn/a/302846.html

相关文章:

  • mysql 配置文件 my.cnf 增加 lower_case_table_names = 1 服务启动不了的原因
  • Bugku CTF_Web——点login咋没反应
  • 浅谈:基于三维场景的视频融合方法
  • vue2.7.14 + vant + vue cli脚手架转vite启动运行问题记录
  • 前端--> nginx-->gateway产生的跨域问题分析
  • Springboot集成syslog+logstash收集日志到ES
  • 从键入网址到显示页面全流程(超详细版)
  • Axure中继器介绍
  • 大屏可视化适配方案
  • 前端数组迭代方法分析
  • 【深度学习】多层感知机的从零开始实现与简洁实现
  • 【RabbitMQ】概述
  • GitHub图床
  • docker 进程的概念
  • 【STM32系统】基于STM32设计的智能垃圾桶(语音、颜色识别、称重、光强、烟雾、人体识别、步进电机、水泵)——文末资料下载
  • android.database.sqlite.SQLiteException: no such table
  • MySQL之DQL子查询
  • Windows系统Docker部署AList并挂载阿里云盘实现远程访问详细教程——“cpolar内网穿透”
  • 双指针算法专题(1)
  • 大模型入门3:理解LLAMA
  • Windows10 如何配置python IDE
  • 从小白到高手:Windows注册表基础运维全攻略
  • Linux软件包循环依赖解决 彻底删除i386架构 更新软件源
  • nginx_shell脚本扩展配置虚拟主机三种方式
  • 为什么np.arrange(0.97,3.0,0.01)最后一个值是3.0018,大于3
  • Qt-常用控件(2)-按钮类和显示类