JAVA设计模式之解释器模式详解

在阎宏博士的《JAVA与模式》一书中开头是这样描述解释器(Interpreter)模式的:

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

解释器模式的结构

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

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

  (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;
    }
   
    @Override
    public boolean equals(Object obj) {
       
        if(obj != null && obj instanceof Constant){
            return this.value == ((Constant)obj).value;
        }
        return false;
    }

@Override
    public int hashCode() {
        return this.toString().hashCode();
    }

@Override
    public boolean interpret(Context ctx) {
       
        return value;
    }

@Override
    public String toString() {
        return new Boolean(value).toString();
    }
   
}

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

代码如下:

public class Variable extends Expression {

private String name;

public Variable(String name){
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
       
        if(obj != null && obj instanceof Variable)
        {
            return this.name.equals(
                    ((Variable)obj).name);
        }
        return false;
    }

@Override
    public int hashCode() {
        return this.toString().hashCode();
    }

@Override
    public String toString() {
        return name;
    }

@Override
    public 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;
    }
    @Override
    public boolean equals(Object obj) {
        if(obj != null && obj instanceof And)
        {
            return left.equals(((And)obj).left) &&
                right.equals(((And)obj).right);
        }
        return false;
    }

@Override
    public int hashCode() {
        return this.toString().hashCode();
    }

@Override
    public boolean interpret(Context ctx) {
       
        return left.interpret(ctx) && right.interpret(ctx);
    }

@Override
    public 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;
    }
    @Override
    public 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;
    }

@Override
    public int hashCode() {
        return this.toString().hashCode();
    }

@Override
    public boolean interpret(Context ctx) {
        return left.interpret(ctx) || right.interpret(ctx);
    }

@Override
    public String toString() {
        return "(" + left.toString() + " OR " + right.toString() + ")";
    }

}

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

代码如下:

public class Not extends Expression {

private Expression exp;
   
    public Not(Expression exp){
        this.exp = exp;
    }
    @Override
    public boolean equals(Object obj) {
        if(obj != null && obj instanceof Not)
        {
            return exp.equals(
                    ((Not)obj).exp);
        }
        return false;
    }

@Override
    public int hashCode() {
        return this.toString().hashCode();
    }

@Override
    public boolean interpret(Context ctx) {
        return !exp.interpret(ctx);
    }

@Override
    public 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));
    }

}

运行结果如下:

(0)

相关推荐

  • Java设计模式之解释器模式_动力节点Java学院整理

    定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 类型:行为类模式 类图: 解释器模式是一个比较少用的模式,本人之前也没有用过这个模式.下面我们就来一起看一下解释器模式. 解释器模式的结构 抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作.具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器Nonterm

  • Java设计模式之解释器模式(Interpreter模式)介绍

    Interpreter定义:定义语言的文法,并且建立一个解释器来解释该语言中的句子. Interpreter似乎使用面不是很广,它描述了一个语言解释器是如何构成的,在实际应用中,我们可能很少去构造一个语言的文法.我们还是来简单的了解一下. 首先要建立一个接口,用来描述共同的操作. 复制代码 代码如下: public interface AbstractExpression { void interpret( Context context );     } 再看看包含解释器之外的一些全局信息 复

  • Java设计模式编程之解释器模式的简单讲解

    0.解释器(Interpreter)模式定义 : 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 属于行为型模式. 解释器模式在实际的系统开发中使用的非常少,因为它会引起效率.性能以及维护等问题. 解释器模式的通用类图如图所示. 1.解释器模式的优点 解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了. 2.解释器模式的缺点 解释器模式会引起类膨胀:每个语

  • 解析Java的设计模式编程之解释器模式的运用

    定义:给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子. 类型:行为类模式 类图: 解释器模式是一个比较少用的模式,本人之前也没有用过这个模式.下面我们就来一起看一下解释器模式.   解释器模式的结构 抽象解释器:声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中主要是一个interpret()方法,称为解释操作.具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器Nonter

  • JAVA设计模式之解释器模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述解释器(Interpreter)模式的: 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 解释器模式的结构 下面就以一个示意性的系统为例,讨论解释器模式的结构.系统的结构图如下所示: 模式所涉及的角色如下所示: (1)抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口.这个接口主要是一个interpre

  • Java设计模式之命令模式详解

    命令模式 定义:将请求封装成对象,这可以让你使用不同的请求.队列.或者日志来参数化其他对象. 何时使用命令模式?当需要将发出请求的对象和执行请求的对象解耦的时候,使用命令模式. 在被解耦的两者之间是通过命令对象进行沟通的.命令对象封装了接收者和一个或一组动作. 调用者通过调用命令对象的execute()方法发出请求,这会使接收者的动作被调用. 调用者可以接收命令当作参数,甚至在运行时动态地进行. 优点: 1.降低了系统耦合度. 2.新的命令可以很容易添加到系统中去. 缺点:使用命令模式可能会导致

  • Java设计模式之原型模式详解

    一.前言 原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式.在实际应用中,原型模式很少单独出现.经常与其他模式混用,他的原型类Prototype也常用抽象类来替代. 该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.在Java中,复制对象是通过clone()实现的,先创建一个原型类,通过实现Cloneable 接口 public class Prototype implements Cloneable { public

  • Java设计模式之代理模式详解

    一.代理模式 代理模式就是有一个张三,别人都没有办法找到他,只有他的秘书可以找到他.那其他人想和张三交互,只能通过他的秘书来进行转达交互.这个秘书就是代理者,他代理张三. 再看看另一个例子:卖房子 卖房子的步骤: 1.找买家 2.谈价钱 3.签合同 4.和房产局签订一些乱七八糟转让协议 一般卖家只在签合同的时候可能出面一下,其他的1,2,4都由中介去做.那你问这样有什么用呢? 首先,一个中介可以代理多个卖房子的卖家,其次,我们可以在不修改卖家的代码的情况下,给他实现房子加价.打广告等等夹带私货的

  • Android编程设计模式之解释器模式详解

    本文实例讲述了Android编程设计模式之解释器模式.分享给大家供大家参考,具体如下: 一.介绍 解释器模式(Interpreter Pattern)是一种用的比较少的行为型模式,其提供了一种解释语言的语法或表达式的方式,该模式定义了一个表达式接口,通过该接口解释一个特定的上下文.在这么多的设计模式中,解释器模式在实际运用上相对来说要少很多,因为我们很少会自己去构造一个语言的文法.虽然如此,既然它能够在设计模式中有一席之位,那么必定有它的可用之处. 二.定义 给定一个语言,定义它的文法的一种表示

  • javascript设计模式之解释器模式详解

    神马是"解释器模式"? 先翻开<GOF>看看Definition:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 在开篇之前还是要科普几个概念: 抽象语法树: 解释器模式并未解释如何创建一个抽象语法树.它不涉及语法分析.抽象语法树可用一个表驱动的语法分析程序来完成,也可用手写的(通常为递归下降法)语法分析程序创建,或直接client提供. 解析器: 指的是把描述客户端调用要求的表达式,经过解析,形成一个抽象语法树的程序. 解

  • JAVA设计模式之访问者模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 分派的概念 变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type):而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type).比如: 复制代码 代码如下: List lis

  • Java设计模式之策略模式详解

    本文实例为大家分享了Java策略模式,供大家参考,具体内容如下 1.策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern). 定义如下: Define a family of algorithms,encapsulate each one,and make them interchangeable.    (定义一组算法,将每个算法都封装起来,并且使它们之间可以互换.) 策略模式的通用类图如下所示: 策略模式的三个角色: ● Context

  • java设计模式之模板方法模式详解

    一.什么是模板方法模式 概念:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 通俗的讲,模板方法模式是通过把不变行为搬到超类,去除子类里面的重复代码提现它的优势,它提供了一个很好的代码复用平台.当不可变和可变的方法在子类中混合在一起的时候,不变的方法就会在子类中多次出现,这样如果摸个方法需要修改则需要修改很多个,虽然这个这个问题在设计之初就应该想好.这个时候模板方法模式就起到了作用了,通过模板方法模式把这些重复出现的

  • java设计模式-装饰者模式详解

    目录 引例 一般解法 装饰者模式 装饰者解法 代码: 抽象类 装饰者 被装饰者 客户端测试 总结: 引例 需求:设现在有单品咖啡:Espresso(意大利浓咖啡)和LongBlack(美式咖啡),调料有Milk(牛奶)和sugar(糖),客户可以点单品咖啡或单品咖啡+调料的组合,计算相应费用.要求在扩展新的咖啡种类时,具有良好的扩展性.改动维护方便. 抛砖引玉,我们先看看两种一般解法. 一般解法 方案一. 枚举创建每一种组合可能,Drink抽象类表示饮料,cost()方法计算价格,子类如Long

随机推荐