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

概述

解释器模式一般来说,我们用的比较少,它提供了一种解释语言的语法或者表达式的方式,比如说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 条评论
登录 后参与评论

相关文章

来自专栏Danny的专栏

设计模式奠基石——UML关系转化为代码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

983
来自专栏C语言及其他语言

C语言经典笔试题

1.以下程序的结果是什么? ? A: main()函数里的i是一个未定义值 B: main()函数的i为1 C: 编译器不允许这种写法 D: main()里i的...

3377
来自专栏数据结构与算法

codevs 1213 解的个数

1213 解的个数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 已知整数x...

3244
来自专栏木子昭的博客

递归并非万能

递归的确简洁, 但性能很差, 因为它进行了大量重复的计算, 如果用递归运算做乘法, 5!*4! = 5*4*3*2*1 * 4*3*2*1显然4!完全可以算...

2555
来自专栏Python爱好者

Python高效编程(二)

1284
来自专栏架构之路

IdentityHashMap的使用场景

IdentityHashMap的使用场景 JDK1.4就加入了这个map类型,它是使用 == 判断相等,而不是hashmap的equals方法判断相等。 那么,...

2533
来自专栏青玉伏案

算法与数据结构(十二) 散列(哈希)表的创建与查找(Swift版)

散列表又称为哈希表(Hash Table), 是为了方便查找而生的数据结构。关于散列的表的解释,我想引用维基百科上的解释,如下所示: 散列表(Hash tab...

19710
来自专栏小樱的经验随笔

hihoCoder #1082 : 然而沼跃鱼早就看穿了一切(字符串处理)

#1082 : 然而沼跃鱼早就看穿了一切 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 ? fjxmlhx每天都在被沼跃鱼刷屏,因...

2675
来自专栏null的专栏

算法类面试题解析——美团2016校招:棋子翻转

题目来自伯乐在线,欢迎有不同答案的同学来一起讨论。 ? 分析: 本题主要是二维数组的操作,对指定的位置上的数字进行翻转,其具体过程如下所示: ? 其基本的过程...

2717
来自专栏逆向技术

C语言_第二讲_规范以及常用数据类型

一丶编码规范基本数据类型 编码规范 任何程序员,都应该有良好的的编码习惯,便于以后的代码可读性和维护 常见了编码规范有 匈牙利命名法 驼峰式大小写 匈牙利命名法...

1910

扫码关注云+社区