java 设计模式之解释器模式①⑨

  • 定义
  • 角色分析
  • 使用场景
  • 代码实现

躁动的心灵,不安的灵魂。在彷徨中挣扎,在迷失中探索。时光飞逝,努力不变。

设计模式学习,近期我会把23种设计模式都写成博客,敬请期待~
—2021/1/26

定义

定义了一个解释器,来解释给定语言和文法的句子。其实质是把语言中的每个符号定义成一个(对象)类,从而把每个程序转换成一个具体的对象树.(编译原理上的编译器)

百度百科

举例理解:
要想和外国人交流,就得通过他们的语言,比如’你好’,把你好传递给翻译官,翻译官翻译出来之后告诉外国人,这里的翻译官就扮演了解释器的责任.

角色分析

UML类图(1.1):

  • 抽象解释器(Expression):具体的解释任务由各个实现类完成。
  • 终结符表达式(VarExpression):实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结表达式,但有多个实例,对应不同的终结符。
  • 非终结符表达式(SymbolExpression):文法中的每条规则对应于一个非终结表达式,非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式
  • 上下文(Calculator): 上下文环境类,包含解释器之外的全局信息
  • 客户类: 客户端,解析表达式,构建抽象语法树,执行具体的解释操作等.

注:
这里的角色不是固定的,以实际场景来确定

非终结符表达式和终结符表达式区别:

  • 非终结符表达式(相当于树的树杈),还会向下执行
  • 终结符表达式(相当于树叶子),不会向下执行

使用场景

  • 一些重复出现的问题可以用一种简单的语言来表达,
  • 一个简单语法需要解释的场景

正则表达式就是采用的解释器模式,但是解释器模式相对于其他的设计模式来说,使用还是太少了!,了解即可.

代码实现

Expression(抽象解释器):

public abstract class Expression {/**** @param var key: a,b,c  |  value: 1,2,3...*/public abstract int interpreter(HashMap<String,Integer> var);
}

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;}
}

这个类只关心运算符左右的值,比如a + b,他只关心 + 号左右的 a 和 b ,具体运算交给其子类

AddExpression(加法运算符):

public class AddExpression extends SymbolExpression {public AddExpression(Expression _left, Expression _right) {super(_left, _right);}//把左右两个表达式运算的结果加起来@Overridepublic int interpreter(HashMap<String, Integer> var) {return super.left.interpreter(var) + super.right.interpreter(var);}
}

通过父类(SymbolExpression)中的left和right相加即可

SubExpression(减法运算符):

public class SubExpression extends SymbolExpression {public SubExpression(Expression _left,Expression _right){super (_left,_right);}//左右两个表达式相减@Overridepublic int interpreter(HashMap<String, Integer> var) {return super.left.interpreter(var) - super.right.interpreter(var);}
}

通过父类(SymbolExpression)中的left和right相加即可

VarExpression(终结表达式,没有子类!)

public class VarExpression extends Expression {private String key;public VarExpression(String _key){this .key = _key;}//从map中取之@Overridepublic int interpreter(HashMap<String, Integer> var) {return var.get( this.key);}
}

这里传递的_key就是对应的字母,假设现在求a+b,这里的_key就是a,b

Calculator获取表达式,计算结果(这个类是关键!)

public class Calculator {//定义的表达式private Expression expression;//构造函数传参,并解析public Calculator(String expStr) {//定义一个堆栈,安排运算的先后顺序Stack<Expression> stack = new Stack<Expression>();//表达式拆分为字符数组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: //公式中的变量stack.push(new VarExpression(String.valueOf(charArray[i])));}}//把运算结果抛出来this.expression = stack.pop();}//开始运算public int run(HashMap<String, Integer> var) {return this.expression.interpreter(var);}
}

分析:

假设现在表达式还是:a+b

当创建Calculator(String expStr)时,传入的就是"a+b"

然后把"a+b"拆分成[a , + , b] 数组,让其来循环

第一次循环 a ,使用栈来压入栈底

第二次循环 + 号,首先执行left = stack.pop();方法,因为当前栈内只有一个,所以此时left等于a,
然后把它赋值给终结者表达式VarExpression(String.valueOf(charArray[++i])) 此时 i == 3,然后把a和b赋值给加法表达式(AddExpression())让他相加即可

所以这里a+b,只循环2次!

java Stack()栈的使用

测试代码(客户端):

        解释器模式 经典案例   \\\\\\\\\\\\\\\\\\\\\\\HashMap<String, Integer> map = new HashMap<>();map.put("a",23);map.put("b",12);Calculator cal = new Calculator("a+b");System.out.println( "运算结果为:" + cal.run(map));

Log图(2.1):

总结:

  • 优点:

    • 扩展性强,若要新增乘,除,添加相应的非终结表达式,修改计算逻辑即可。
  • 缺点

    • 需要建大量的类,因为每一种语法都要建一个非终结符的类。
    • 解释的时候采用递归调用方法,导致有时候函数的深度会很深,影响效率。

总得来说,解释器模式用的比较少,理解即可.

完整代码

去设计模式/设计原则主页

原创不易,您的点赞就是对我最大的支持~

java 设计模式之解释器模式(十九)相关推荐

  1. Java设计模式分为创建模式, 结构模式, 行为模式 3种类型

    Java设计模式之创建模式包括: Factory,    工厂模式 Singleton,   单例模式 Builder,    建造模式 Prototype,    原型模式 Java设计模式之结构模 ...

  2. java备忘录模式应用场景_图解Java设计模式之备忘录模式

    图解Java设计模式之备忘录模式 游戏角色状态恢复问题 游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态. ...

  3. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  4. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

    Java设计模式Ⅶ 1.访问者模式 1.1 访问者模式概述 1.2 代码理解 2.迭代器模式 2.1 迭代器模式概述 2.2 代码理解 3.观察者模式 3.1 观察者模式概述 3.2 代码理解 4.中 ...

  5. Java设计模式(建造者模式-适配器模式-桥接模式)

    Java设计模式Ⅲ 1.建造者模式 1.1 建造者模式概述 1.2 建造者模式的注意事项和细节 1.3 代码理解 2.适配器模式 2.1 类适配器模式 2.1.1 代码理解 2.2 对象适配器模式 2 ...

  6. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

  7. 折腾Java设计模式之建造者模式

    博文原址:折腾Java设计模式之建造者模式 建造者模式 Separate the construction of a complex object from its representation, a ...

  8. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  9. java设计模式5--原型模式(Prototype)

    本文地址:http://www.cnblogs.com/archimedes/p/java-prototype-pattern.html,转载请注明源地址. 原型模式 用原型实例指定创建对象的种类,并 ...

最新文章

  1. QPS过万,redis大量连接超时怎么解决?
  2. [转载]逐步建设企业DevOps能力
  3. Java 性能优化实战记录(3)--JVM OOM的分析和原因追查
  4. 学习笔记Spark(六)—— Spark SQL应用(1)—— Spark SQL简介、环境配置
  5. vocabulary of ERP
  6. django 1.8 官方文档翻译:5-1-4 内建的Widget
  7. Django Model View Template 之间的简单交互 (二)
  8. PHP微信公众号支付弹出“NaN:undefined”解决方法
  9. Linux命令使用练习一
  10. 红宝书(javascirpt高级程序设计)学习笔记(一)
  11. python开三次方_python 三次方
  12. 博图可以用c语言编程吗,S7300能用C语言编程吗?
  13. AIS数据-渔船的货船的区分(Distinction between the cargo ships of fishing boats)
  14. 【lidar】单目深度估计与伪雷达点云、可视化
  15. 【萧蕊冰】ui设计和交互设计的区别是什么?
  16. 基于Springboot和Mybatis的文件上传与下载
  17. js date日期格式化
  18. 访问服务器显示无法访问目标主机,ip无法访问目标主机
  19. js将url转换二维码
  20. 【数据增强】用cv2旋转图像并自定义填充背景颜色(主要用到cv2.getRotationMatrix2D 和 cv2.warpAffine)

热门文章

  1. 使用python-docx读取doc,docx文档
  2. 心率变异性和身心健康
  3. MATLAB 使用python代码
  4. php上传图片模范代码
  5. 泰坦服务器装系统,深海泰坦X8Ti笔记本安装win10系统操作方法
  6. 网格交易 python_VNPY网格交易法优化
  7. 回退git add操作
  8. linux进程的使用xps,linux kernel 网络协议栈之xps特性详解
  9. 拟牛顿法及其matlab实现
  10. ios键盘通知和自定义键盘