Java终结符,Java描述设计模式(14):解释器模式

一、解释器模式

1、基础概念

解释器模式是对象的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的表达式。

2、模式图解

031c59a8fa460c56f07205d5f8f69ce5.png

3、核心角色

(1)、抽象表达式

Express:声明具体表达式角色需要实现的抽象接口,该接口主要提供一个interpret()方法,称做解释操作。

(2)、终结符表达式

TerminalExpress:实现抽象表达式角色接口,主要是一个interpret()方法;每个终结符都有一个具体终结表达式与之相对应。比如解析c=a+b,a和b是终结符,解析a和b的解释器就是终结符表达式。

(3)、非终结符表达式

NotTerminalExpress:每一条规则都需要一个具体的非终结符表达式用来衔接,一般是指运算符或者逻辑判断,比如c=a+b,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。

(4)、环境容器

DataMap:一般是用来存放各个终结符所对应的具体值,比如c=a+b转换为c=1+2。这些信息需要一个存放环境。

4、源代码实现

类图结构

be8d3996ee5d28142e10ec66888aa728.png

源码实现

public class C01_InScene {

public static void main(String[] args) {

DataMap dataMap = new DataMap();

TerminalExpress terminalExpress1 = new TerminalExpress("num1");

TerminalExpress terminalExpress2 = new TerminalExpress("num2");

TerminalExpress terminalExpress3 = new TerminalExpress("num3");

dataMap.putData(terminalExpress1, 1);

dataMap.putData(terminalExpress2, 2);

dataMap.putData(terminalExpress3, 3);

// 1+2-3 = 0

System.out.println(new Minus(

new Add(terminalExpress1,terminalExpress2), terminalExpress3)

.interpret(dataMap));

}

}

// 解释器接口

interface Express {

Integer interpret(DataMap dataMap) ;

}

// 非终结符表达式

abstract class NotTerminalExpress implements Express {

Express express1,express2;

public NotTerminalExpress(Express express1, Express express2){

this.express1 = express1;

this.express2 = express2;

}

}

// 终结符表达式: 1+2 终结符: 1 和 2

class TerminalExpress implements Express {

public String field ;

public TerminalExpress (String field){

this.field = field ;

}

@Override

public Integer interpret(DataMap dataMap) {

return dataMap.getData(this);

}

}

// 加法表达式

class Add extends NotTerminalExpress {

public Add (Express e1, Express e2) {

super(e1, e2);

}

// 将两个表达式相减

@Override

public Integer interpret(DataMap context) {

return this.express1.interpret(context) + this.express2.interpret(context);

}

}

// 减法表达式

class Minus extends NotTerminalExpress {

public Minus (Express e1, Express e2) {

super(e1, e2);

}

// 将两个表达式相减

@Override

public Integer interpret(DataMap context) {

return this.express1.interpret(context) - this.express2.interpret(context);

}

}

// 数据容器

class DataMap {

private Map dataMap = new HashMap<>() ;

public void putData (Express key,Integer value){

dataMap.put(key,value) ;

}

public Integer getData (Express key){

return dataMap.get(key) ;

}

}

二、Spring框架应用

1、源码案例

import org.springframework.expression.Expression;

import org.springframework.expression.spel.standard.SpelExpressionParser;

public class SpringTest {

public static void main(String[] args) {

SpelExpressionParser parser = new SpelExpressionParser () ;

Expression expression = parser.parseExpression("(1+3-2)*3") ;

Integer result = (Integer)expression.getValue() ;

System.out.println("result="+result);

}

}

2、代码分析

(1)Expression结构

表达式接口:具有不同的实现类。

interface Expression

class CompositeStringExpression implements Expression

class LiteralExpression implements Expression

class SpelExpression implements Expression

核心方法:

Object getValue() throws EvaluationException;

(2)SpelExpressionParser结构

SpelExpressionParser extends TemplateAwareExpressionParser

TemplateAwareExpressionParser implements ExpressionParser

interface ExpressionParser

(3)ExpressionParser接口

public interface ExpressionParser {

Expression parseExpression(String var1) ;

Expression parseExpression(String var1, ParserContext var2) ;

}

(4)Expression获取

根据不同的条件获取不同的Expression对象。这里产生类的依赖关系。

源码位置:TemplateAwareExpressionParser

public Expression parseExpression(String expressionString,

ParserContext context)

throws ParseException {

if (context == null) {

context = NON_TEMPLATE_PARSER_CONTEXT;

}

return context.isTemplate() ?

this.parseTemplate(expressionString, context) :

this.doParseExpression(expressionString, context);

}

三、模式总结

场景

编译器、运算符表达式、正则表达式、机器人等。

优点

当有一个表达式或者语言需要解释执行,该场景下的内容可以考虑使用解释器模式,使程序具有良好的扩展性。

缺点

解释器模式会引起类膨胀,会导致程序执行和调试非常复杂,不容易理解。

四、源代码地址

GitHub·地址

https://github.com/cicadasmile/model-arithmetic-parent

GitEE·地址

https://gitee.com/cicadasmile/model-arithmetic-parent

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值