解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。

解释器模式的结构

  下面就以一个示意性的系统为例,讨论解释器模式的结构。系统的结构图如下所示:

  模式所涉及的角色如下所示:

  (1)抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作。

  (2)终结符表达式(Terminal Expression)角色:实现了抽象表达式角色所要求的接口,主要是一个interpret()方法;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如有一个简单的公式R=R1+R2,在里面R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。

  (3)非终结符表达式(Nonterminal Expression)角色:文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+"就是非终结符,解析“+”的解释器就是一个非终结符表达式。

  (4)环境(Context)角色:这个角色的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,我们给R1赋值100,给R2赋值200。这些信息需要存放到环境角色中,很多情况下我们使用Map来充当环境角色就足够了。

  为了说明解释器模式的实现办法,这里给出一个最简单的文法和对应的解释器模式的实现,这就是模拟Java语言中对布尔表达式进行操作和求值。

  在这个语言中终结符是布尔变量,也就是常量true和false。非终结符表达式包含运算符and,or和not等布尔表达式。这个简单的文法如下:

    Expression  ::= Constant | Variable | Or | And | Not

    And     ::= Expression 'AND' Expression

    Or     ::= Expression 'OR' Expression

    Not     ::= 'NOT' Expression

    Variable  ::= 任何标识符

    Constant    ::= 'true' | 'false'

  解释器模式的结构图如下所示:

  

  源代码

  抽象表达式角色

public abstract class Expression {/*** 以环境为准,本方法解释给定的任何一个表达式*/public abstract boolean interpret(Context ctx);/*** 检验两个表达式在结构上是否相同*/public abstract boolean equals(Object obj);/*** 返回表达式的hash code*/public abstract int hashCode();/*** 将表达式转换成字符串*/public abstract String toString();
}

  一个Constant对象代表一个布尔常量

public class Constant extends Expression{private boolean value;public Constant(boolean value){this.value = value;}@Overridepublic boolean equals(Object obj) {if(obj != null && obj instanceof Constant){return this.value == ((Constant)obj).value;}return false;}@Overridepublic int hashCode() {return this.toString().hashCode();}@Overridepublic boolean interpret(Context ctx) {return value;}@Overridepublic String toString() {return new Boolean(value).toString();}}

  一个Variable对象代表一个有名变量

public class Variable extends Expression {private String name;public Variable(String name){this.name = name;}@Overridepublic boolean equals(Object obj) {if(obj != null && obj instanceof Variable){return this.name.equals(((Variable)obj).name);}return false;}@Overridepublic int hashCode() {return this.toString().hashCode();}@Overridepublic String toString() {return name;}@Overridepublic boolean interpret(Context ctx) {return ctx.lookup(this);}}

  代表逻辑“与”操作的And类,表示由两个布尔表达式通过逻辑“与”操作给出一个新的布尔表达式的操作

public class And extends Expression {private Expression left,right;public And(Expression left , Expression right){this.left = left;this.right = right;}@Overridepublic boolean equals(Object obj) {if(obj != null && obj instanceof And){return left.equals(((And)obj).left) &&right.equals(((And)obj).right);}return false;}@Overridepublic int hashCode() {return this.toString().hashCode();}@Overridepublic boolean interpret(Context ctx) {return left.interpret(ctx) && right.interpret(ctx);}@Overridepublic String toString() {return "(" + left.toString() + " AND " + right.toString() + ")";}}

  代表逻辑“或”操作的Or类,代表由两个布尔表达式通过逻辑“或”操作给出一个新的布尔表达式的操作

public class Or extends Expression {private Expression left,right;public Or(Expression left , Expression right){this.left = left;this.right = right;}@Overridepublic boolean equals(Object obj) {if(obj != null && obj instanceof Or){return this.left.equals(((Or)obj).left) && this.right.equals(((Or)obj).right);}return false;}@Overridepublic int hashCode() {return this.toString().hashCode();}@Overridepublic boolean interpret(Context ctx) {return left.interpret(ctx) || right.interpret(ctx);}@Overridepublic String toString() {return "(" + left.toString() + " OR " + right.toString() + ")";}}

  代表逻辑“非”操作的Not类,代表由一个布尔表达式通过逻辑“非”操作给出一个新的布尔表达式的操作

public class Not extends Expression {private Expression exp;public Not(Expression exp){this.exp = exp;}@Overridepublic boolean equals(Object obj) {if(obj != null && obj instanceof Not){return exp.equals(((Not)obj).exp);}return false;}@Overridepublic int hashCode() {return this.toString().hashCode();}@Overridepublic boolean interpret(Context ctx) {return !exp.interpret(ctx);}@Overridepublic String toString() {return "(Not " + exp.toString() + ")";}}

  环境(Context)类定义出从变量到布尔值的一个映射

public class Context {private Map<Variable,Boolean> map = new HashMap<Variable,Boolean>();public void assign(Variable var , boolean value){map.put(var, new Boolean(value));}public boolean lookup(Variable var) throws IllegalArgumentException{Boolean value = map.get(var);if(value == null){throw new IllegalArgumentException();}return value.booleanValue();}
}

  客户端类

public class Client {public static void main(String[] args) {Context ctx = new Context();Variable x = new Variable("x");Variable y = new Variable("y");Constant c = new Constant(true);ctx.assign(x, false);ctx.assign(y, true);Expression exp = new Or(new And(c,x) , new And(y,new Not(x)));System.out.println("x=" + x.interpret(ctx));System.out.println("y=" + y.interpret(ctx));System.out.println(exp.toString() + "=" + exp.interpret(ctx));}}

  运行结果如下:

转载于:https://www.cnblogs.com/jiangzhaowei/p/7287368.html

《JAVA与模式》之解释器模式相关推荐

  1. Java设计模式学习记录-解释器模式

    前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...

  2. 行为型模式:解释器模式

    原文首发: 行为型模式:解释器模式 十一大行为型模式之十:解释器模式. 简介 姓名 :解释器模式 英文名 :Interpreter Pattern 价值观 :不懂解释到你懂​ 个人介绍 : Given ...

  3. 设计模式之观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式

    前言 这是设计模式的最后一章,包含了剩余的 行为型模式 中的 观察者模式.中介者模式.迭代器模式.访问者模式.备忘录模式.解释器模式 系列文章 第一章:7种设计原则之单一职责原则.接口隔离原则.依赖倒 ...

  4. 十三、中介者模式与解释器模式详解

    19.中介者模式 19.1.课程目标 1.掌握中介者模式和解释器模式的应用场景. 2.了解设计群聊的底层逻辑. 3.掌握解析表达式的基本原理. 4.理解中介者模式和解释器模式的优缺点. 19.2.内容 ...

  5. 图解Java设计模式学习笔记——行为型模式(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式)

    一.模板方法模式(模板模式)--钩子方法 1.需求-豆浆制作问题 编写制作豆浆的程序,说明如下: 制作豆浆的流程选材-->添加配料-->浸泡-->放到豆浆机打碎. 通过添加不同的配料 ...

  6. Java设计模式(九)—中介者模式、备忘录模式、解释器模式

    本章目录标题 第21章 中介者模式 21.1 应用场景:智能家居 21.2 传统方式 21.3 中介者模式 21.4 应用案例:智能家居 21.5 中介者模式的注意事项 第22章 备忘录模式 22.1 ...

  7. 三、行为型模式【访问者模式、备忘录模式、命令模式、解释器模式、中介模式】

    访问者模式 允许一个或者多个操作应用到一组对象上,解耦操作和对象本身,保持类职责单一.满足开闭原则以及应对代码的复杂性. 多态是一种动态绑定,可以在运行时获取对象的实际类型,来运行实际类型对应的方法. ...

  8. GOF23 设计模式 之命令模式、解释器模式、访客模式

    这三种模式不常用 命令模式: 把一个请求封装成对象,也可以把很多个请求封装成对象,然后对这写请求命令进行 的处理 (请求排队,记录日志,撤销) 应用场景: 数据库的事务 ,命令的撤销和恢复 ***** ...

  9. 设计模式之美——行为型3:迭代模式、访问者模式、命令模式、解释器模式、中介模式

    迭代器模式 迭代器模式的原理和实现 迭代器模式(Iterator Design Pattern),也叫作游标模式(Cursor Design Pattern). 迭代器模式.它用来遍历集合对象.这里说 ...

  10. 设计模式8(享元模式,解释器模式)

    享元模式 对象的缓冲池,共享内部状态相同的对象,类似幼儿园系统中缓存的Query 解释器模式 定义一个上下文,并对其进行解释执行 转载于:https://www.cnblogs.com/jspdelp ...

最新文章

  1. 考研计算机专业英语题型,考研英语一题型及分值
  2. php 字符串内容过滤,php过滤字符串内容的
  3. 使用t-sql语句修改表中的某些数据及数据类型。_测试开发工程师数据库篇(一)...
  4. MySQL数据库安装与Navicat Premium 12 安装与破解
  5. 【译】RAID的概念和RAID对于SQL性能的影响
  6. 广义Fibonacci数列找循环节
  7. 模板:2-SAT问题
  8. Android9.0 http网络请求失败问题的处理
  9. jquery表格自动补全插件——datagrid
  10. Hive 1.1.0 某些字段的查询结果为NULL
  11. Popush项目团队开发章程
  12. 创建react项目并启动出现的报错及解决
  13. php判断电话号码是否为空号,如何批量检测手机号码是否为空号、无效号码?
  14. 想开发一个在线的合同模板管理套件
  15. QT widget宽高比
  16. Python进行拉勾网数据爬取框架与思路
  17. WKwebview弹框报错Attempt to present UIAlertController on XXwhich is already presenting (null)
  18. 用户态协议栈之epoll实现
  19. 结合阿里云 FC 谈谈我对 FaaS 的理解
  20. Android获取QQ名片赞数量,教你如何提高QQ名片赞数量 如何增加QQ赞数量

热门文章

  1. Python爬虫实践(一) -- 社交网站用户信息爬取
  2. 购物搜索引擎架构的变与不变
  3. JIRA /mnt/server/atlassian-jira-6.3.6-standalone/bin/start-jira.sh
  4. JS中的拖动之—— ondragstart,ondrag,ondragend , ondragenter , ondragover , ondragleave, ondrop 的区别...
  5. 自动化测试===unittest和requests接口测试案例,测试快递查询api(二)
  6. 【CentOS】Centos下pip的安装
  7. eclipse jar打包详解
  8. 新发布GoldenGate 12c版本中的主要特性
  9. devcloud 基础架构
  10. ASIHttpRequest没更新,MKNetWorKit更优越