设计模式--解释器模式

通过解释器来实现四则运算:如计算a+b-c的值,

具体要求如下:

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

传统方案介绍:

  1. 编写一个方法,接收表达式的形式,然后根据用户输入的数值进行解析,得到结果。
  2. 命令模式使得请求发送者和请求接受者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。

传统方案带来的问题:

  1. 如果加入了新的运算符,比如说*/等等,不利于扩展,让另外一个方法解析会造成程序结构不清晰,十分混乱。
  2. 解决方案:可以考虑使用解释器模式。即:表达式->解释器->结果

解释器模式的基本介绍:

  1. 在编译原理中,一个算数表达式通过词法分析器形成词法单元,而这些词法单元通过语法分析器构建语法分析树,最终形成一个抽象的语法分析树。这里的词法分析器语法分析器都可以看做是解释器。
  2. 解释器模式(Interpreter Pattern)是指给定一个语言表达式,定义了它的文法的一种表示,并定义了一个解释器,使用该解释器来解释语言中的句子(表达式)。
  3. 应用场景:
  • 可以将一个需要执行中的语言的句子表示为一个抽象语法树。
  • 一些重复的问题可以用一种简单的语言来表达。
  • 一些简单语法需要解释器的场景。
  1. 这样的例子还有很多:比如编译器、运算表达式、正则表达式、机器人等。

解释器模式类图:

对原理类图的说明即解释器模式的角色和职责:

  1. Context:是环境对象角色。它含有解释器之外的全局信息。
  2. AbstractExpression:是抽象表达式角色,它是一个抽象类或者接口,声明一个抽象的解释操作。这个方法为抽象语法树中所有的节点所共享。
  3. TerminalExpression:为终结表达式,实现与文法中的终结符相关的解释操作。
  4. NonTerminalExpression:为非终结表达式,为文法中的非终结符相关的解释操作。
  5. 说明:输入Context和TerminalExpression信息通过Client输入即可。

解释器模式完成四则运算:

  1. UML类图:

关键代码:

package com.xia.designmode.study.interpreterpattern;

import java.util.HashMap;

/**

* 解释器模式--TerminalExpression角色, 变量解释器

* 通过HashMap键值对可以获取到变量的值。

* */

public class VarExperssion implements Expression{

private String key;//a,b,c

public VarExperssion(String key) {

this.key = key;

}

/**

* 根据变量名称返回对应的值。

* */

@Override

public int interpret(HashMap<String, Integer> varHashMap) {

return varHashMap.get(key);

}

}

package com.xia.designmode.study.interpreterpattern;

import java.util.HashMap;

/**

* 解释器模式--具体的NonTerminalExpression角色, 加法解释器

* */

public class AddExperssion extends AbstractSymbolExperssion{

public AddExperssion(Expression leftExpression, Expression rightExpression) {

super(leftExpression, rightExpression);

}

/*

* 处理相加

* var 的值依旧是前面的 {a=20,b=10}键值对

* */

@Override

public int interpret(HashMap<String, Integer> varHashMap) {

//leftExpression.interpret(varHashMap)返回左侧表达式解析后的值

//rightExpression.interpret(varHashMap)返回右侧表达式解析后的值

return leftExpression.interpret(varHashMap)+rightExpression.interpret(varHashMap);

}

}

package com.xia.designmode.study.interpreterpattern;

import java.util.HashMap;

/**

* 解释器模式--NonTerminalExpression角色, 符号解释器

* 它是抽象的运算符号解析器,每个运算符号都和自己的左右两个数字有关系

* 但是左右两个符号有可能是两个解析结果,无论和何种类型,都是Expression的实现类

* */

public abstract class AbstractSymbolExperssion implements Expression{

Expression leftExpression;

Expression rightExpression;

public AbstractSymbolExperssion(Expression leftExpression, Expression rightExpression) {

this.leftExpression = leftExpression;

this.rightExpression = rightExpression;

}

/**

* 本身是抽象的,所以并不实现下面的方法。它是让他的子类来实现的。

* */

}

解释器模式在Spring框架中的应用源码分析:

  1. Spring SpelExpressionParser中就是用了解释器模式。
  2. 代码分析:

  1. 模式的角色说明:
  • Expression接口,表达式接口,下面有不同的实现类,比如我们用到的SpelExpression、CompositeStringException
  • 使用的时候,根据创建的不同的parser对象,返回不同的Exception对象。

解释器模式注意事项和细节:

  1. 有当一个语言需要解释执行时,可将该语言中的句子表示为一个抽象语法树,就可以考虑使用解释器模式,让程序有良好的扩展性。
  2. 应用场景:编译器、运算表达式计算、正则表达式、机器人等。
  3. 使用解释器带来的问题,解释器模式会引起类膨胀。解释器模式采用递归调用方法,最终导致的是调试异常复杂,效率可能会降低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值