[设计模式/Java] 设计模式之解释器模式【27】

概述:解释器模式 := Interpreter Pattern ∈ 行为型模式

模式定义

  • 解释器模式Interpreter Pattern)提供了评估语言的语法表达式的方式

属于行为型模式

  • 解释器模式给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

  • 这种模式被用在 SQL 解析符号处理引擎等。

  • 模式的意图

定义一种语言的文法表示,并创建一个解释器,该解释器能够解释该语言中的句子。。

  • 主要解决的问题

解释器模式用于构建一个能够解释特定语言或文法句子的解释器

模式结构

解释器模式包含以下几个主要角色:

  • 抽象表达式(Abstract Expression):定义了解释器的抽象接口,声明了解释操作的方法,通常是一个抽象类或接口。
  • 终结符表达式(Terminal Expression):实现了抽象表达式接口的终结符表达式类,用于表示语言中的终结符(如变量、常量等),并实现了对应的解释操作。
  • 非终结符表达式(Non-terminal Expression):实现了抽象表达式接口的非终结符表达式类,用于表示语言中的非终结符(如句子、表达式等),并实现了对应的解释操作。
  • 上下文(Context):包含解释器之外的一些全局信息,在解释过程中提供给解释器使用,通常用于存储变量的值、保存解释器的状态等。
  • 客户端(Client):创建并配置具体的解释器对象,并将需要解释的表达式传递给解释器进行解释。

适用场景

  • 当某一特定类型的问题频繁出现,并且可以通过一种简单的语言来表达这些问题的实例时。

实现方式

  • 定义【文法】:明确语言的终结符和非终结符。
  • 构建【语法树】:根据语言的句子构建对应的语法树结构。
  • 创建【环境类】:包含解释过程中所需的全局信息,通常是一个HashMap。

关键代码

  • 终结符与非终结符:定义语言的文法结构。
  • 环境类:存储解释过程中需要的外部环境信息。

模式特点

优点

  • 可扩展性好:容易添加新的解释表达式的方式。
  • 灵活性:可以根据需要轻松扩展或修改文法。
  • 易于实现简单文法:对于简单的语言,实现起来相对容易。

缺点

  1. 使用场景有限:只适用于适合使用解释的简单文法。
  2. 维护困难:对于复杂的文法,维护和扩展变得困难。
  3. 类膨胀:可能会产生很多类,每个文法规则对应一个类。
  4. 递归调用:解释器模式通常使用【递归调用】,这可能难以理解和跟踪。

使用建议

  • 在需要解释执行语言中的句子时,考虑使用解释器模式。
  • 确保文法简单,以避免系统变得过于复杂。
  • 解释器模式在 Java 中可能不是首选,如果遇到适用场景,可以考虑使用如expression4J之类的库来代替。

案例实践

案例总结

  • 编译器:解释器模式可以用于编译器设计,将源代码解释为目标代码。
  • 正则表达式:解释器模式可以用于解析和执行正则表达式。
  • SQL解析:解释器模式可以用于解析和执行SQL语句。
  • 文本模板渲染引擎 : 用于将各层级的环境信息渲染到文本模板中,生成最终的SQL、HTML等。著名的文本模板渲染引擎有:Jinjia(2) / Thymeleaf / Freemaker 等。

CASE 解释器模式的简单实现(性别/婚姻)

  • 我们将创建一个接口 Expression 和实现了 Expression 接口的实体类。
  • 定义作为上下文中主要解释器的 TerminalExpression 类。
  • 其他的类 OrExpression、AndExpression 用于创建组合式表达式
  • InterpreterPatternDemo,我们的演示类使用 Expression 类创建规则和演示表达式的解析。

[设计模式/Java] 设计模式之解释器模式【27】

表达式接口 : Expression

public interface Expression {    public boolean interpret(String context); } 

表达式接口的实现类: TerminalExpression / OrExpression / AndExpression

  • TerminalExpression
public class TerminalExpression implements Expression {        private String data;      public TerminalExpression(String data){       this.data = data;     }      @Override    public boolean interpret(String context) {       if(context.contains(data)){          return true;       }       return false;    } } 
  • OrExpression
public class OrExpression implements Expression {    private Expression expr1 = null;    private Expression expr2 = null;      public OrExpression(Expression expr1, Expression expr2) {        this.expr1 = expr1;       this.expr2 = expr2;    }      @Override    public boolean interpret(String context) {             return expr1.interpret(context) || expr2.interpret(context);    } } 
  • AndExpression
public class AndExpression implements Expression {    private Expression expr1 = null;    private Expression expr2 = null;      public AndExpression(Expression expr1, Expression expr2) {        this.expr1 = expr1;       this.expr2 = expr2;    }      @Override    public boolean interpret(String context) {             return expr1.interpret(context) && expr2.interpret(context);    } } 

Client : InterpreterPatternDemo

  • InterpreterPatternDemo : 使用 Expression 类来创建规则,并解析它们。
public class InterpreterPatternDemo {    //规则:Robert 和 John 是男性    public static Expression getMaleExpression(){       Expression robert = new TerminalExpression("Robert");       Expression john = new TerminalExpression("John");       return new OrExpression(robert, john);        }      //规则:Julie 是一个已婚的女性    public static Expression getMarriedWomanExpression(){       Expression julie = new TerminalExpression("Julie");       Expression married = new TerminalExpression("Married");       return new AndExpression(julie, married);        }      public static void main(String[] args) {       Expression isMale = getMaleExpression();       Expression isMarriedWoman = getMarriedWomanExpression();         System.out.println("John is male? " + isMale.interpret("John"));       System.out.println("Julie is a married women? "        + isMarriedWoman.interpret("Married Julie"));    } } 

out

John is male? true Julie is a married women? true 

CASE 开源 SQL 解析引擎 - Apche Calcite

  • 推荐文献

CASE 开源语法分析工具 - Antlr

  • 推荐文献

Y 推荐文献

X 参考文献

发表评论

评论已关闭。

相关文章