Java设计模式之解释器模式

概述

解释器模式是一种用得比较少的行为型模式.提供了一种解释语言的语法或表达式的方式.
通过定义一个表达式接口,解释一个特定的上下文.

定义

给定一个语言,解释器模式可以定义出其文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子.

解释器中涉及到的文法,就是符合一定规则的语句结构.
如 abcd…….cdef(ab开头,ef结尾,中间N个cd)中,根据N值的不同,可以得到不同的字符串如,abef,abcdef,abcdcdef….
假设我们有如下推导式
S ::= abA*ef
A ::= cd
其中 ::=表示推导,*表示闭包,意思是A可以有0~N个重复,S是初始符号,abef和cd是终结符号.
像这样的从一个具体的符号出发,通过不断地应用一些产生式规则 从而生成一个字符串的集合,我们将描述这个集合的文法称为形式文法.

给定一个语言(如由abcdef六个字符组成的字符串集合),定义它的文法的一种表示(S::=abA*ef,A::=cd)并定义一个解释器,解释器使用该表示来解释语言中的句子.
其中的解释器类似一个翻译机

使用场景

  • 某个简单的语言需要解释执行并且可以将该语言中的语句表示为一个抽象语法树的时候.
  • 在某些特定的领域出现不断重复的问题时,可以将该领域的问题转化为一种语法规则下的语句,并构建解释器来解释该语句.

UML

解释器模式UML

其中涉及到的角色有:

AbstractExpression: 抽象表达式,声明一个抽象的解释操作父类,定义一个抽象的解释方法,具体的实现由子类解释器完成/
TerminalExpression: 终结符表达式,实现文法中与终结符有关的解释操作,文法中每一个终结符都有一个具体的终结表达式与之对应
NonterminalExpression: 非终结符表达式,实现文法中与非终结符有关的解释操作
Context: 上下文环境类,包含解释器之外的全局信息
Client: 客户端,解析表达式,构建抽象语法树,执行具体的解释操作等.

实例

如下我们通过对算术表达式的解释来看一个解释器模式的实现,
如表达式m+n+p中,如果我们使用解释器模式对该表达式进行解释,那么m,n,p代表的三个字母可以看成是终结符号,而+代表的运算符则可以看成是非终结符号

  • 首先建立抽象解释器表示数学运算
public abstract class ArithmeticExpression {

  public abstract int interptet();
}

解释器中定义了interptet()方法,ArithmeticExpression有两个直接子类,NumExpression,和OperatorExpression

  • 建立NumExpression,对数字进行解释
public class NumExpression extends ArithmeticExpression {
  private int num;

  public NumExpression(int _num) {
    num = _num;
  }

  @Override public int interptet() {
    return num;
  }
}
  • 建立OperatorExpression,对运算符进行解释
public abstract class OperatorExpression extends ArithmeticExpression {
  protected ArithmeticExpression mArithmeticExpression1,mArithmeticExpression2;

  public OperatorExpression(ArithmeticExpression _arithmeticExpression1,
      ArithmeticExpression _arithmeticExpression2) {
    mArithmeticExpression1 = _arithmeticExpression1;
    mArithmeticExpression2 = _arithmeticExpression2;
  }
}
  • AdditionExpression,OperatorExpression的直接子类,加法运算解释器
public class AdditionExpression extends OperatorExpression {
  public AdditionExpression(ArithmeticExpression _arithmeticExpression1,
      ArithmeticExpression _arithmeticExpression2) {
    super(_arithmeticExpression1, _arithmeticExpression2);
  }

  @Override public int interptet() {
    return mArithmeticExpression1.interptet() + mArithmeticExpression2.interptet();
  }
}
  • 新增业务逻辑处理类
public class Calculator {

  protected Stack<ArithmeticExpression> mArithmeticExpressionStack = new Stack<>();

  public Calculator(String expression) {
    ArithmeticExpression arithmeticExpression1, arithmeticExpression2;
    String[] elements = expression.split(" ");
    for (int i = 0; i < elements.length; ++i) {
      switch (elements[i].charAt(0)) {
        case '+':
          arithmeticExpression1 = mArithmeticExpressionStack.pop();
          arithmeticExpression2 = new NumExpression(Integer.valueOf(elements[++i]));
          mArithmeticExpressionStack.push(
              new AdditionExpression(arithmeticExpression1, arithmeticExpression2));
          break;
        default:
          mArithmeticExpressionStack.push(new NumExpression(Integer.valueOf(elements[i])));
          break;
      }
    }
  }

  public int calculate() {
    return mArithmeticExpressionStack.pop().interptet();
  }
}
  • 客户端调用
// 解释计算123+124+125+126的运算结果
Calculator calculator = new Calculator("123+124+125+126");
   Log.d(TAG, "setBtnClick: -->" + calculator.calculate());

优缺点

优点
  • 灵活性强,如上边的例子,当我们想对文法规则进行扩展延伸时,只需要增加相应的非终结符解释器,并在构建语法树的时候使用新增的解释器对象进行具体的解释即可.
缺点
  • 因为每一条文法都可以对应至少一个解释器,会生成大量的类,导致后期维护困难,而且对应复杂的文法,构建语法树会显得异常繁琐.

实例代码

DesignPatterns

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言文法的表示,并定义了一个解释器,用于解释语言中的句子。它将一个问题分成两个部分:一部分是语言的文法规则,另一部分是解释器,用来解释规则中的句子。解释器模式可以用于处理一些简单的语言,如数学表达式、正则表达式等。 实现方式: 1. 定义抽象表达式类(AbstractExpression),它是所有表达式类的父类,声明了抽象的解释方法。 2. 定义终结符表达式类(TerminalExpression),它实现了抽象表达式类中的解释方法,用于解释语言中的终结符。 3. 定义非终结符表达式类(NonterminalExpression),它也实现了抽象表达式类中的解释方法,用于解释语言中的非终结符。 4. 定义上下文类(Context),它包含了解释器需要的一些全局信息。 5. 客户端使用时,先创建一个上下文对象,然后将需要解释的语言句子作为参数传入解释器对象中,解释器对象将句子解释成相应的结果。 优点: 1. 可扩展性好,增加新的文法规则只需要添加相应的非终结符表达式类即可。 2. 易于实现语法分析。 缺点: 1. 对于复杂的文法规则,解释器模式的类数量可能会很大,增加程序的复杂性。 2. 执行效率较低,因为需要递归调用解释器对象。 适用场景: 1. 可以用于处理一些简单的语言,如数学表达式、正则表达式等。 2. 当语言的文法规则比较复杂时,可以使用解释器模式进行语法分析。 3. 当需要对语言进行增强时,可以使用解释器模式添加新的文法规则。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值