设计模式二十四章经之解释器模式

概述

解释器模式一般来说,我们用的比较少,它提供了一种解释语言的语法或者表达式的方式,比如说1+2,我们可以通过解释器模式告诉你这是一个加法。

使用场景

  • 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题。
  • 可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
  • 一些重复出现的问题可以用一种简单的语言来进行表达。
  • 一个简单语法需要解释的场景。

具体实现

我们现在通过一个简单的例子,比如向你解释这个文本是否包含某个内容。

我们先写个一个接口。这个接口的意图就是文本是否包含某个内容,返回一个boolean值。

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

现在我们写一个类是实现这个接口,实现我们刚才所说的点:

public class TerminalExpression implements IExpression {

   private String data;

   public TerminalExpression(String data){
      this.data = data; 
   }

   @Override
   public boolean interpret(String context) {
      if(context.contains(data)){
         return true;
      }
      return false;
   }
}

现在我们写2个类去实现我们刚才说的内容:

public class OrExpression implements IExpression {

   private IExpression expr1 = null;
   private IExpression expr2 = null;

   public OrExpression(IExpression expr1, IExpression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {        
      return expr1.interpret(context) || expr2.interpret(context);
   }
}
public class AndExpression implements IExpression {

   private IExpression expr1 = null;
   private IExpression expr2 = null;

   public AndExpression(IExpression expr1, IExpression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {        
      return expr1.interpret(context) && expr2.interpret(context);
   }
}

通过代码我们可以发现,一个是只要包含其一,另一个必须是都要包含,现在我们写一个Demo看看效果:

public class Expression {
    public static IExpression getMaleExpression() {
        IExpression robert = new TerminalExpression("Robert");
        IExpression john = new TerminalExpression("John");
        return new OrExpression(robert, john);
    }

    public static IExpression getMarriedWomanExpression() {
        IExpression julie = new TerminalExpression("Julie");
        IExpression married = new TerminalExpression("Married");
        return new AndExpression(julie, married);
    }

    public static void main(String[] args) {
        IExpression isMale = getMaleExpression();
        IExpression isMarriedWoman = getMarriedWomanExpression();

        System.out.println("John is male? " + isMale.interpret("John"));
        System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married Julie"));
    }
}

运行得出:

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

如果我们将代码改成:System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married "));

那么运行结果则是:

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

总结

优点:

  • 可扩展性比较好,灵活。
  • 增加了新的解释表达式的方式。
  • 易于实现简单文法。

缺点:

  • 可利用场景比较少。
  • 对于复杂的文法比较难维护。
  • 解释器模式会引起类膨胀。
  • 解释器模式采用递归调用方法。

原文发布于微信公众号 - 我就是马云飞(coding_ma)

原文发表时间:2018-06-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏喵了个咪的博客空间

zephir-(5)类型

#zephir-类型# ? ##前言## 先在这里感谢各位zephir开源技术提供者 Zephir既可以使用动态类型也可以使用静态类型,这是zephir独特的一...

3739
来自专栏互联网杂技

28个JavaScript 编程黑科技:还有这种操作!

从来不需要声明一个变量的值是undefined,因为JavaScript会自动把一个未赋值的变量置为undefined。所有如果你在代码里这么写,会被鄙视的

1313
来自专栏Jimoer

Java设计模式学习记录-原型模式

1485
来自专栏维C果糖

Guava 指南 之「使用和避免 null」

使用和避免null “null,糟糕透啦!” —— Doug Lea. “我称null为百亿美金的错误!” —— C. A. R. Hoare. 轻...

2147
来自专栏学习力

《Java从入门到放弃》JavaSE入门篇:变量

1445
来自专栏云霄雨霁

排序----快速排序

1230
来自专栏张善友的专栏

检查Python对象

编程环境中的对象很象现实世界中的对象。实际的对象有一定的形状、大小、重量和其它特征。实际的对象还能够对其环境进行响应、与其它对象交互或执行任务。计算机中的对象试...

20210
来自专栏猿人谷

浅谈C/C++中的指针和数组(一)

                                                       浅谈C/C++中的指针和数组(一)       指...

2235
来自专栏菜鸟计划

angularjs filter详解

过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果。 主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的...

3798
来自专栏微信公众号:Java团长

JavaSE入门篇:变量

图片上的各种餐具,就是变量,因为同一个盘子可以在不同的时间装不同的菜,在这一桌可以装土豆肉丝,在下一桌可以装清炒黄瓜(当然,这个盘子还是要洗洗干净滴)。

1132

扫码关注云+社区

领取腾讯云代金券