第二十二章 解释器模式

news2024/11/23 20:14:17

文章目录

  • 前言
  • 一、解释器模式基本介绍
    • 解释器模式的原理类图
  • 二、通过解释器模式来实现四则运算
    • 完整代码
    • 抽象表达式类 Expression
    • 变量表达式类 VarExpression
    • 抽象运算符号解析器 SymbolExpression
    • 加法解释器 AddExpression
    • 减法解释器 SubExpression
    • 计算器类 Calculator
    • Clint 测试类
  • 三、解释器模式在Spring框架应用的源码剖析
  • 四、解释器模式的注意事项和细节


前言

在这里插入图片描述

在这里插入图片描述


一、解释器模式基本介绍

在这里插入图片描述

解释器模式的原理类图

在这里插入图片描述
在这里插入图片描述

二、通过解释器模式来实现四则运算

在这里插入图片描述

完整代码

抽象表达式类 Expression

package tanchishell.SJMS.interpreter;

import java.util.HashMap;

/**
 * 抽象类表达式,通过 HashMap 键值对, 可以获取到变量的值
 *
 *
 *
 */
public abstract class Expression {

    // a + b - c
// 解释公式和数值, key 就是公式(表达式) 参数[a,b,c], value 就是就是具体值
// HashMap {a=10, b=20}
    public abstract int interpreter(HashMap<String, Integer> var);
}

变量表达式类 VarExpression

package tanchishell.SJMS.interpreter;

import java.util.HashMap;

/**
 * 变量的解释器
 */
public class VarExpression extends Expression {
    private String key; // key=a,key=b,key=c

    public VarExpression(String key) {
        this.key = key;
    }

    // var 就是{a=10, b=20}
    // interpreter 根据 变量名称,返回对应值
    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return var.get(this.key);
    }

}

抽象运算符号解析器 SymbolExpression

package tanchishell.SJMS.interpreter;


import java.util.HashMap;

/**
 * 抽象运算符号解析器 这里,每个运算符号,都只和自己左右两个数字有关系,
 * 但左右两个数字有可能也是一个解析的结果,无论何种类型,都是 Expression 类的实现类
 */
public class SymbolExpression extends Expression {

    protected Expression left;
    protected Expression right;

    public SymbolExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    //因为 SymbolExpression 是让其子类来实现,因此 interpreter 是一个默认实现
    @Override
    public int interpreter(HashMap<String, Integer> var) {
        return 0;

    }
}

加法解释器 AddExpression

package tanchishell.SJMS.interpreter;


import java.util.HashMap;

/**
 * 加法解释器
 */
public class AddExpression extends SymbolExpression {

    public AddExpression(Expression left, Expression right) {
        super(left, right);
    }

    //处理相加
    //var 仍然是 {a=10,b=20}.. //一会我们 debug 源码,就 ok
    public int interpreter(HashMap<String, Integer> var) {
         //super.left.interpreter(var) : 返回 left 表达式对应的值 a = 10
        //super.right.interpreter(var): 返回 right 表达式对应值 b = 20
        return super.left.interpreter(var) + super.right.interpreter(var);
    }
}

减法解释器 SubExpression

package tanchishell.SJMS.interpreter;

import java.util.HashMap;

/**
 * 减法解释器
 *
 */
public class SubExpression extends SymbolExpression {

    public SubExpression(Expression left, Expression right) {
        super(left, right);
    }

    //求出 left 和 right 表达式相减后的结果
    public int interpreter(HashMap<String, Integer> var) {
        return super.left.interpreter(var) - super.right.interpreter(var);
    }
}

计算器类 Calculator

package tanchishell.SJMS.interpreter;

import java.util.HashMap;
import java.util.Stack;

public class Calculator {

    // 定义表达式
    private Expression expression;
    // 构造函数传参,并解析

    public Calculator(String expStr) { // expStr = a+b
        // 安排运算先后顺序
        Stack<Expression> stack = new Stack<>();
        // 表达式拆分成字符数组
        char[] charArray = expStr.toCharArray();// [a, +, b]
        Expression left = null;
        Expression right = null;
        //遍历我们的字符数组, 即遍历 [a, +, b]
        //针对不同的情况,做处理
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]) {
                case '+': //
                    left = stack.pop();// 从 stack 取出 left => "a"
                    right = new VarExpression(String.valueOf(charArray[++i]));// 取出右表达式 "b"
                    stack.push(new AddExpression(left, right));// 然后根据得到 left 和 right 构建 AddExpresson 加入stack
                    break;
                case '-': //
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubExpression(left, right));
                    break;
                default:
                    //如果是一个 Var 就创建要给 VarExpression 对象,并 push 到 stack
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
                    break;
            }
        }
        //当遍历完整个 charArray 数组后,stack 就得到最后 Expression
        this.expression = stack.pop();
    }

    public int run(HashMap<String, Integer> var) {
        //最后将表达式 a+b 和 var = {a=10,b=20}
        //然后传递给 expression 的 interpreter 进行解释执行
        return this.expression.interpreter(var);
    }
}

Clint 测试类

package tanchishell.SJMS.interpreter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;

public class ClientTest {

    public static void main(String[] args) throws IOException {

        String expStr = getExpStr(); // a+b
        HashMap<String, Integer> var = getValue(expStr);// var {a=10, b=20}

        Calculator calculator = new Calculator(expStr);
        System.out.println("运算结果:" + expStr + "=" + calculator.run(var));
    }

    // 获得表达式
    public static String getExpStr() throws IOException {
        System.out.print("请输入表达式:");
        return (new BufferedReader(new InputStreamReader(System.in))).readLine();
    }

    // 获得值映射
    public static HashMap<String, Integer> getValue(String expStr) throws IOException {
        HashMap<String, Integer> map = new HashMap<>();
        for (char ch : expStr.toCharArray()) {
            if (ch != '+' && ch != '-') {
                if (!map.containsKey(String.valueOf(ch))) {
                    System.out.print("请输入" + String.valueOf(ch) + "的值:");
                    String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    map.put(String.valueOf(ch), Integer.valueOf(in));
                }
            }
        }
        return map;
    }

}


输出

请输入表达式:a+b
请输入a的值:10
请输入b的值:10
运算结果:a+b=20

三、解释器模式在Spring框架应用的源码剖析

在这里插入图片描述
在这里插入图片描述

四、解释器模式的注意事项和细节

在这里插入图片描述

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

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

相关文章

【C++】仅需一文速通继承

文章目录 1.继承的概念及定义继承的概念继承的定义定义格式:继承关系和访问限定符继承基类成员访问方式的变化 2.基类和派生类对象赋值转换3.继承中的作用域4.派生类的默认成员函数题目:设计出一个类A,让这个类不能被继承(继承了也没用) 5.继承与友元6.继承与静态成员7.复杂的菱…

VK Cup 2017 - Round 1 A - Bear and Friendship Condition(并查集维护大小 + dfs 遍历图统计边数)

题目大意&#xff1a; 给你一些n个点m条边&#xff0c;如果三个点&#xff08;a,b,c&#xff09;是合法的&#xff0c;当且仅当 a-b,b-c,c-a都有一条边&#xff0c;问你这个图是否合法&#xff0c;如果有一个或两个点视为合法 思路 考虑什么图才是个合法图&#xff1a;除了点…

Spring 更简单的读取和存储对象

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 前面介绍了通过配置文件的方式来存储 Bean 对象&#xff0c;那么有没有更简单的方式去存储 Bean 对象&#xff1f; 有以下 2 种方…

【论文】LearningDepth from Single Monocular Images

2005 NIPS 文章目录 特征提取卷积核的使用Multiscale 多尺度提取特征特征的相对深度 模型结论特征提取数据集导致的error 文章使用了Markov 随机场(Markov Random Fields, MRF) 从单图像上直接估计出图像的深度信息。 与RGBD输入数据不同的是&#xff0c;文章中采用了YCbCr数据…

知识点总结-DAY1

1. 请解释OSI模型中每一层的作用 应用层&#xff1a;为用户提供服务&#xff0c;处理应用程序之间交换的数据。 表示层&#xff1a;处理数据在网络上的表示形式&#xff0c;如加密和解密、压缩和解压缩等。 会话层&#xff1a;建立、维护和终止两个节点之间的会话&#xff0c…

安全防御 --- IPSec理论

IPSec 1、概述&#xff1a; 是IETF&#xff08;Internet Engineering Task Force&#xff09;制定的一组开放的网络安全协议&#xff0c;在IP层通过数据来源认证、数据加密、数据完整性和抗重放功能来保证通信双方Internet上传输数据的安全性。 IPSec安全服务 机密性完整性…

雨季时,骑行经过泥泞路段该怎么办?

泥泞路段骑行是一项需要技巧和勇气的挑战。在泥泞路段骑行&#xff0c;骑友又叫玩泥巴&#xff0c;不仅需要良好的车技和身体素质&#xff0c;还需要有足够的经验和判断力&#xff0c;以应对各种突发情况。下面&#xff0c;将从多个角度介绍泥泞路段骑行的挑战和技巧&#xff0…

宏观经济笔记--社会消费品零售总额

我们讨论了GDP的三个分项&#xff1a;投资、消费、净出口。投资我们前面已经介绍了&#xff0c;消费这一个分项我们还一直没有讨论。消费最重要的数据是每个月月中统计局公布的社会消费品零售总额。 一般的论调中&#xff0c;认为消费是三个GDP驱动项中最健康的一项&#xff0…

2023-5-4-Lua语言学习

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

openQA----基于openQA新增指定版本的openSUSE的iso镜像进行测试

【原文链接】openQA----基于openQA新增指定版本的openSUSE的iso镜像进行测试 &#xff08;1&#xff09;执行如下命令下载openSUSE的测试脚本&#xff0c;它会从openSUSE的测试脚本github地址 /usr/share/openqa/script/fetchneedles&#xff08;2&#xff09;然后执行如下命…

在 SourceTree 中使用 rebase (win10)

原始状态 创建两个分支 dev1 dev2, 并且推送到远端 切换到dev1 做一些修改并提交dev1-1&#xff0c;注意不要推送到到远端 切换到master分支&#xff0c;拉取最新的代码 切换到dev1 分支&#xff0c;进行变基操作&#xff0c;右击master分支 推送dev1分支到远端 切换到master分…

如何快速获取已发表学术论文的期刊封面及目录(caj格式下载和caj转pdf)

目录 1 下载caj格式的封面和目录 2 CAJ格式的封面和目录转PDF格式 在进行职称评审或成果申报时&#xff0c;一般要求提交你发表的成果所在的期刊的当期封面和目录。本文就手把手带带你制作一个期刊目录。 重要提示&#xff1a;下载期刊封面和目录需要你有知网账号&#xff0…

iOS 17预计开放侧载,游戏安全对抗将迎来新高度

近日&#xff0c;据彭博社报道&#xff0c;iOS 17预计开放“侧载”机制。所谓的“侧载”是指&#xff1a;iPhone用户下载APP时&#xff0c;可选择不在APP store中下载&#xff0c;可在相关APP官网或者第三方应用市场进行下载。 众所周知&#xff0c;APP闭源生态是苹果公司最核…

C++ 基础二

C 核心编程 1 内存分区模型 内存分区模型 代码区&#xff1a;存放函数的二级制代码&#xff0c;由操作系统进行管理的 全局区&#xff1a;存放全局变量和静态变量以及常量 栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值&#xff0c;局部变量等 堆区&…

5.1 矩阵的特征值和特征向量

学习步骤&#xff1a; 学习特征值和特征向量的定义和性质&#xff0c;我会采取以下方法&#xff1a; 1. 学习线性代数基础知识&#xff1a;特征值和特征向量是线性代数中的重要概念&#xff0c;需要先掌握线性代数的基础知识&#xff0c;例如向量、矩阵、行列式、逆矩阵、转置…

Bark:基于转换器的文本到音频模型

Bark是由Suno创建的一个基于转换器的文本到音频模型。Bark可以生成高度逼真的多语言语音以及其他音频&#xff0c;包括音乐、背景噪音和简单的音效。该模型还可以产生非语言交流&#xff0c;如大笑、叹息和哭泣。为了支持研究社区&#xff0c;我们正在提供对预先训练的模型检查…

生物信息学中---数据集不平衡的处理方法

1.NearMiss&#xff1a; NearMiss 是 Mani 等人根据数据分布特征&#xff0c;基于 KNN 算法提出的欠采样方案&#xff0c; 对多数类样本利用随机欠采样来达到数据平衡。 根据不同数据采样的距离&#xff0c;可以分为三类&#xff1a; NearMiss-1、 NearMiss-2 和 NearMiss-3。…

什么是数据库分片?

什么是数据库分片&#xff1f; 数据库分片是指将一个大型数据库拆分成多个小型数据库&#xff0c;每个小型数据库称为一个分片。通过这种方式&#xff0c;可以将数据库的负载分散到多个服务器上&#xff0c;从而提高数据库的性能和可伸缩性。 为什么需要数据库分片&#xff1f…

从一到无穷大 #7 Database-as-a-Service租户隔离挑战与解决措施

文章目录 引言计算侧多租户隔离2DFQSQLVMRetro 其他隔离方法其他 引言 在云环境中租户之间的资源共享对于运营商的成本效益来说非常重要&#xff0c;但是一个主要问题是租户之间的资源隔离&#xff0c;这通常与Qos息息相关&#xff0c;从多租户的角度讲&#xff0c;安全性/性能…

ChatGPT 不好用?那你看下这份 Prompt 工程指南

作为大型语言模型接口&#xff0c;ChatGPT 生成的响应令人刮目相看&#xff0c;然而&#xff0c;解锁其真正威力的关键还是在于提示工程。 在本文中&#xff0c;我们将揭示制作提示的专家级技巧&#xff0c;以生成更准确、更有意义的响应。无论你使用 ChatGPT 是为了服务客户、…