Java描述设计模式(14):解释器模式

本文源码:GitHub·点这里 || GitEE·点这里

一、解释器模式

1、基础概念

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

2、模式图解

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、源代码实现

  • 类图结构

  • 源码实现

    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<Express,Integer> 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

原文地址:https://blog.51cto.com/14439672/2443434

时间: 2024-11-11 09:56:32

Java描述设计模式(14):解释器模式的相关文章

大话设计模式_解释器模式(Java代码)

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 简单描述:一个AbstractExpression类,多个子类,存在一个Interpret方法,转义Context对象的信息.客户端根据信息实例化不同的Expression类,并调用其转义方法(这个过程可以使用简单工厂+反射进行) 大话设计模式中的截图: 代码例子: 假设HTML代码解释器: (1)第一类标签<HTML>(开始)/<HEAD>(头信息)/<BODY&g

折腾Java设计模式之解释器模式

解释器模式 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 意图 给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子. 主要解决 对于一些固定文法构建一个解释句子的解释器. 何时使用 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子.这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题. 如何解

Java描述设计模式(05):原型模式

一.原型模式简介 1.基础概念 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象. 2.模式结构 原型模式要求对象实现一个可以"克隆"自身的接口,这样就可以通过复制一个实例对象本身来创建一个新的实例.这样一来,通过原型实例创建新的对象,就不再需要关心这个实例本身的类型,只要实现了克隆自身的方法,就可以通过这个方法来获取新的对象,而无须再去通过new来创建. 3.代码实现 1).UML关系图 Java描述设计模

设计模式之解释器模式(Interpreter)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

GOF23设计模式之解释器模式和访问器模式的理解

设计模式之解释器模式Interpreter      是一种不常用的设计模式      用于描述如何构成一个简单的语言解释器,主要用于使用面向对象语言开发的编译器和解释器设计.      当我们需要开发一种新的语言时,可以考虑使用解释器模式.      尽量不要使用解释器模式,后期维护会有很大麻烦.在项目中可以使用jruby,Groovy,java的js引擎来代替解释器的作用,弥补java语言的不足. 开发中常见的场景:      EL表达式的处理      正则表达式解释器      SQL语

java常用设计模式之 工厂模式

工厂模式: 定义 一个用于创建对象的接口,让子类决定实例化哪一个类. 一句话概括: 是一个类的实例化延迟到其子类.     适用于 以下情况: ①:当一个类 ,不知道它所必须创建的对象的类的时候. ②:当一个类,希望由它的子类来指定它所创建的对象的时候. ③:当类将创建对象的职责给多个帮助子类中的一个,并且希望将哪一个帮助子类是代理这一信息局部化的时候. 说明: ① Product :定义工厂方法所创建的对象的接口. ② ConcreteProduct:实现Product 接口. ③ Creat

如何让孩子爱上设计模式 ——14.策略模式(Strategy Pattern)

如何让孩子爱上设计模式 --14.策略模式(Strategy Pattern) 描述性文字 本节讲解的是行为型设计模式中的第一个模式: 策略模式, 这个模式非常简单,也很好理解. 定义一系列的算法,把每个算法封装起来,并使得他们可以相互替换, 让算法独立于使用它的客户而变化. 一般用来替换if-else,个人感觉是面向过程与面向对象思想的 过渡,这里举个简易计算器的栗子,帮助理解~ 普通的if-else/switch计算器 普通的面向过程if-else简易计算器代码如下: 运行结果如下: 这里我

23种设计模式之解释器模式

解释器模式的定义 定义: 给定一门语言,定义它的文法的一种表示, 并定义一个解释器, 该解释器使用该表示来解释语言中的句子. 其类图如下: 其中的角色说明: AbstractExpression 抽象解释器: 具体的解释任务由各个实现类完成 TerminalExpression 终结符表达式: 实现与文法中的元素相关联的解释操作, 通常一个解释器模式中只有一个终结符表达式, 但有多个实例,对应不同的终结符 NonterminalExpression 非终结符表达式: 文法中的每条规则对应于一个非

C#设计模式:解释器模式(Interpreter Pattern)

一,C#设计模式:解释器模式(Interpreter Pattern) 1,解释器模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的模式不断重复出现,并且容易抽象为语法规则的问题”才适合使用解释器模式2,解释器设计模式每个解释的类有自己的规则,并且与其他业务规则不冲突 二,如下代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; u