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

概述

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

相关文章

来自专栏编程

pythonic之路(一)

pythonic之路(一) 一、 中不要直接将语句与 、 、 做比较 python中隐含为 的对象: 数值 (不是字符 ) 空容器,比如空list 、空tupl...

18810
来自专栏云霄雨霁

排序----快速排序

1150
来自专栏Java爬坑系列

【JAVA零基础入门系列】Day13 Java类的继承与多态

  继承是类的一个很重要的特性,什么?你连继承都不知道?你是想气死爸爸好继承爸爸的遗产吗?(滑稽)   开个玩笑,这里的继承跟我们现实生活的中继承还是有很大区别...

1965
来自专栏菜鸟计划

angularjs filter详解

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

3618
来自专栏维C果糖

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

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

2067
来自专栏Phoenix的Android之旅

Java的克隆

说到克隆,本质都是使用一个已经实例化完成的对象的副本。 对于基本类型比较简单。比方说我们想复制一个变量,

912
来自专栏Android开发指南

Effecvtive Java Note

2955
来自专栏陈满iOS

编程语言傻傻分不清:弱类型、强类型、动态类型、静态类型

这篇文章综合介绍了四种分类,特别地,为了方便大家快速有效的学习,笔者尝试用思维导图的办法描述编程语言的区别。一般来讲,看第一个图就够了。但如果你想更深入地了解,...

1651
来自专栏Jimoer

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

1345
来自专栏学习力

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

1385

扫码关注云+社区