尚硅谷设计模式学习(二十一)解释器模式

25 篇文章 12 订阅
订阅专栏

以四则运算问题引入解释器模式

先输入表达式的形式,比如 a+b+c-d+e,要求表达式的字母不能重复,在分别输入  a、b、c、d的值,最后求出结果。

传统方案

编写一个方法,接收表达式的形式,然后根据用户输入的数值进行解析,得到结果

问题分析

如果加入新的运算符,比如 *  / 等等,不利于扩展,另外让一个方法来解析会造成程序结构混乱, 
不够清晰。

一、解释器模式

1、基本介绍

在编译原理中,一个算术表达式通过词法分析器形成词法单元,而后这些词法单元再通过语法分析器构建语法分析树,最终形成一颗抽象的语法分析树。这里的词法分析器和语法分析器都可以看做是解释器。

解释器模式(Interpreter  Pattern):是指给定一个语言(表达式),定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子(表达式)

应用场景

  • 将一个需要解释执行的语言中的句子表示为一个抽象语法树 
  • 一些重复出现的问题可以用一种简单的语言来表达
  • 编译器、运算表达式计算、正则表达式、机器人等

  • Context:是环境角色,含有解释器之外的全局信息.
  • AbstractExpression:抽象表达式, 声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享。
  • TerminalExpression:为终结符表达式,实现与文法中的终结符相关的解释操作
  • NonTermialExpression:为非终结符表达式,为文法中的非终结符实现解释操作

终结符非终结符在计算机科学和语言学的领域是用来指定推导规则的元素。在某个形式语法之中,终结符和非终结符是两个不交的集合。

通俗的说,终结符不可再分,非终结符可再分,通过下面的例子会解释

2、代码实现

具体思路

加法解释器,减法解释器就是非终结符表达式,因为它们还能再分解成left,right

变量解释器就是终结符表达式

抽象类解释器Expression

public abstract class Expression {
    /**
     * 根据变量名称,返回对应值
     * 例如: a + b ,key就是公式参数[a , b], value就是就是具体值
     * HashMap  {a=10,  b=20}
     */
    public abstract int interpret(HashMap<String,Integer> var);
}

变量解释器VarExpression

//变量解释器
public class VarExpression extends Expression {

    private String key; //key = a , b

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

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

 抽象运算符号解析器SymbolExpression,这里每个运算符号都只和自己左右两个数字有关系,

//抽象运算符号解析器,这里每个运算符号都只和自己左右两个数字有关系
public abstract class SymbolExpression extends Expression {

    protected Expression left;
    protected Expression right;

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

    //让其子类来实现
    public abstract int interpret(HashMap<String,Integer> var);
}

加法解释器AddExpression 

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

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

    ///求left 和 right表达式相加后的结果
    @Override
    public int interpret(HashMap<String, Integer> var) {
        return super.left.interpret(var) + super.right.interpret(var);
    }
}

减法解释器SubExpression

public class SubExpression extends SymbolExpression {

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

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

 计算器Calculator

public class Calculator {

    //定义表达式
    private Expression expression;

    //构造函数传参并解析
    public Calculator(String expStr){
        //通过栈来进行运算操作
        Stack<Expression> stack = new Stack();
        //表达式拆分成字符数组
        char[] charArray = expStr.toCharArray();

        Expression left = null;
        Expression right = null;

        //遍历我们的字符数组,针对不同的情况做处理
        for (int i = 0; i < charArray.length; i++){
            switch (charArray[i]){
                case '+':
                    left = stack.pop();
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    stack.push(new AddExpression(left, right));
                    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])));
            }
        }
        this.expression = stack.pop();
    }

    public int run(HashMap<String,Integer> map){
        return this.expression.interpret(map);
    }
}

 测试

public class Client {
    public static void main(String[] args) throws IOException {
        //获得表达式
        String expStr = getExpStr();
        //去掉空格
        String str = expStr.replaceAll(" ", "");
        //获得值映射
        HashMap<String, Integer> map = getValue(str);
        Calculator calculator = new Calculator(str);
        //得到计算结果
        int result = calculator.run(map);
        System.out.println(expStr + " = " + result);
    }
    
    //获得表达式
    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 - c + d
请输入 a 的值:1
请输入 b 的值:2
请输入 c 的值:3
请输入 d 的值:4
a + b - c + d = 4

这里说明一下在Calculator构造器里计算完成后expression的值,这个expression是什么呢?

this.expression = stack.pop();

具体计算过程如图所示 

得到expression后会执行run方法

    public int run(HashMap<String,Integer> map){
        return this.expression.interpret(map);
    }

这里进行的是递归运算,debug一下这段代码会有更好的理解。

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

当有一个语言需要解释执行,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序具有良好的扩展性

使用解释器可能带来的问题:解释器模式会引起类膨胀、解释器模式采用递归调用方法,将会导致调试非常复杂、效率可能降低。

解释器模式(详解版)——小马同学@Tian
SigleDog的博客
12-01 289
解释器模式(详解版) 在软件开发中,会遇到有些问题多次重复出现,而且有一定的相似性和规律性。如果将它们归纳成一种简单的语言,那么这些问题实例将是该语言的一些句子,这样就可以用“编译原理”中的解释器模式来实现了。 虽然使用解释器模式的实例不是很多,但对于满足以上特点,且对运行效率要求不是很高的应用实例,如果用解释器模式来实现,其效果是非常好的,本文将介绍其工作原理与使用方法。 模式的定义与特点 解释器(Interpreter)模式的定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语
尚硅谷设计模式源码笔记课件.zip
08-04
行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...
第十七章 解释器模式
weixin_43054590的博客
09-11 372
一、模式示例 1.1、原理 1、定义 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。 2、介绍 意图:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 主要解决:对于一些固定文法构建...
设计模式解释器模式
JustToFaith
10-12 2530
解释器模式 解释器模式(Interpreter Pattern)属于行为模式,它定义一个语言的文法,并且建立一个解释器来解释该语言中的句子,这里的“语言”是指使用规定格式和语法的代码。 解释器模式的四个角色 AbstractExpression(抽象表达式):声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享。 TerminalExpression(终结符表达式):实现与文法中的终结符相关的解释操作。比如 c = a + b,其中 a 和 b 就是终结符,而对应 a 和 b 的解释器就是终结符
Java之23种设计模式解析_尚硅谷_宋红康
12-14
15. **Interpreter(解释器模式)** - **定义**:给定一个语言,定义它的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 - **应用场景**:解释表达式时。 16. **Memento(备忘录...
尚硅谷Java设计模式(图解+框架源码剖析).zip
最新发布
11-06
尚硅谷提供的这个资料包“Java设计模式(图解+框架源码剖析)”显然是为了帮助开发者深入理解和应用这些模式。尽管没有具体的标签,我们可以从标题推测,这个资源可能涵盖了各种设计模式的理论介绍、图形化解释以及...
Java设计模式尚硅谷笔记
10-10
笔记主要涵盖了多种经典的设计模式,以下是对这些模式的详细解释: 1. 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。在Java中,通常通过双重检查锁定(Double-Check Locking)或静态内部类...
Java之23种设计模式解析
05-20
包括责任链模式、命令模式解释器模式、迭代器模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。它们可以帮助我们更好地管理复杂系统的动态行为。 每一种设计模式都有其特定的适用...
深入解析尚硅谷Java设计模式与框架源码
资源摘要信息:"读书笔记尚硅谷Java设计模式图解+框架源码剖析.zip" 文件标题及描述表明该压缩包文件包含了关于Java设计模式学习笔记以及对Java框架源码的剖析。尚硅谷是一个知名的IT教育品牌,专注于提供高质量...
写文章

热门文章

  • UTF-8 与 UTF-16编码详解 28297
  • 尚硅谷周阳老师 SpringCloud第二季学习笔记 11018
  • 函数式(Functional)接口 9607
  • Docker容器网络更改 9447
  • SSM整合完整流程讲解 8571

分类专栏

  • 源码 5篇
  • Spring系列 7篇
  • SpringCloud 18篇
  • SpringBoot 5篇
  • juc 20篇
  • JVM 21篇
  • 计算机基础 6篇
  • 中间件
  • RabbitMQ 2篇
  • Dubbo 1篇
  • Redis 3篇
  • ActiveMQ 3篇
  • Zookeeper 1篇
  • Maven 3篇
  • 常见问题 3篇
  • MySQL 1篇
  • JavaWeb 17篇
  • Linux 2篇
  • Docker 6篇
  • Java基础 40篇
  • 项目 2篇
  • 设计模式 25篇

最新评论

  • UTF-8 与 UTF-16编码详解

    key12315: 博主很用心,点赞一个,另外推荐一个在线utf-16编码解码的工具: https://config.net.cn/tools/utf16.html

  • SpringCloud学习笔记(七) Hystrix 断路器

    骑着蜗牛去追星星: 一直loding 不是版本问题,而是需要启动使用了HystrixCommand命令的微服务

  • Spring原理学习(七)JDK动态代理与CGLIB代理底层实现

    小鲁蛋儿: 【黑马满叔spring高级50讲!容器和Bean部分,深入原理,就业必备,这是你唯一认清spring的机会!-黑马程序员武汉中心-哔哩哔哩】 https://b23.tv/2wr7xGQ

  • Spring原理学习(七)JDK动态代理与CGLIB代理底层实现

    小鲁蛋儿: 黑马程序员满老师的spring源码课

  • Spring原理学习(七)JDK动态代理与CGLIB代理底层实现

    菜腿1994: 想问下博主参考的的书籍或者视频是哪些,感觉还挺深入的

最新文章

  • 解决SqlServer自增主键使用MybatisPlus批量插入报错问题
  • Java 实现简易计算器
  • 谷粒学院SpringSecurity认证流程详解
2024年1篇
2023年19篇
2022年191篇
2021年4篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鲁蛋儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家安阳景观园林玻璃钢仿铜雕塑玻璃钢雕塑蒸馒头玻璃钢树脂景观雕塑桐乡酒店玻璃钢花盆滁州动物玻璃钢雕塑制作深圳贴马赛克玻璃钢雕塑安顺玻璃钢雕塑制作玻璃钢卡通河马雕塑太原玻璃钢骆驼雕塑玻璃钢奶牛雕塑 微信许昌定做玻璃钢雕塑厂电话北京玻璃钢雕塑订做东莞玻璃钢卡通雕塑定做玻璃钢雕塑 东莞昌邑玻璃钢胸像雕塑户外玻璃钢花盆图片大全苏州汕头玻璃钢动物雕塑固原玻璃钢雕塑价格韶关玻璃钢动物雕塑供应商家西安公园玻璃钢雕塑订做价格绵阳玻璃钢海豚雕塑厂家安徽个性化玻璃钢雕塑方法玻璃钢仿真水果雕塑多少钱西安玻璃钢雕塑定做厂西宁动物玻璃钢雕塑公司海淀玻璃钢花盆固原玻璃钢花盆金山区大型玻璃钢雕塑优选企业北京玻璃钢园林雕塑成都欧式玻璃钢雕塑销售电话香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化