• 《Java设计模式》之解释器模式


    解释器模式是类的行为模式。给定一个语言之后,解释器模式能够定义出其文法的一种表示,并同一时候提供一个解释器。

    client能够使用这个解释器来解释这个语言中的句子。

    解释器模式的结构

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

      模式所涉及的角色例如以下所看到的:

      (1)抽象表达式(Expression)角色:声明一个全部的详细表达式角色都须要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作。

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

      (3)非终结符表达式(Nonterminal Expression)角色:文法中的每一条规则都须要一个详细的非终结符表达式。非终结符表达式通常是文法中的运算符或者其它keyword,比方公式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'

      解释器模式的结构图例如以下所看到的:

      源码

      抽象表达式角色

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:08:58 
    6.  *  
    7.  * @类说明 :抽象表达式角色 
    8.  */  
    9. public abstract class Expression {  
    10.     /** 
    11.      * 以环境为准,本方法解释给定的不论什么一个表达式 
    12.      */  
    13.     public abstract boolean interpret(Context ctx);  
    14.   
    15.     /** 
    16.      * 检验两个表达式在结构上是否同样 
    17.      */  
    18.     public abstract boolean equals(Object obj);  
    19.   
    20.     /** 
    21.      * 返回表达式的hash code 
    22.      */  
    23.     public abstract int hashCode();  
    24.   
    25.     /** 
    26.      * 将表达式转换成字符串 
    27.      */  
    28.     public abstract String toString();  
    29. }  


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

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:09:35 
    6.  *  
    7.  * @类说明 :一个Constant对象代表一个布尔常量 
    8.  */  
    9. public class Constant extends Expression {  
    10.   
    11.     private boolean value;  
    12.   
    13.     public Constant(boolean value) {  
    14.         this.value = value;  
    15.     }  
    16.   
    17.     @Override  
    18.     public boolean equals(Object obj) {  
    19.   
    20.         if (obj != null && obj instanceof Constant) {  
    21.             return this.value == ((Constant) obj).value;  
    22.         }  
    23.         return false;  
    24.     }  
    25.   
    26.     @Override  
    27.     public int hashCode() {  
    28.         return this.toString().hashCode();  
    29.     }  
    30.   
    31.     @Override  
    32.     public boolean interpret(Context ctx) {  
    33.   
    34.         return value;  
    35.     }  
    36.   
    37.     @Override  
    38.     public String toString() {  
    39.         return new Boolean(value).toString();  
    40.     }  
    41.   
    42. }  


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

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:10:16 
    6.  *  
    7.  * @类说明 :一个Variable对象代表一个有名变量 
    8.  */  
    9. public class Variable extends Expression {  
    10.   
    11.     private String name;  
    12.   
    13.     public Variable(String name) {  
    14.         this.name = name;  
    15.     }  
    16.   
    17.     @Override  
    18.     public boolean equals(Object obj) {  
    19.   
    20.         if (obj != null && obj instanceof Variable) {  
    21.             return this.name.equals(((Variable) obj).name);  
    22.         }  
    23.         return false;  
    24.     }  
    25.   
    26.     @Override  
    27.     public int hashCode() {  
    28.         return this.toString().hashCode();  
    29.     }  
    30.   
    31.     @Override  
    32.     public String toString() {  
    33.         return name;  
    34.     }  
    35.   
    36.     @Override  
    37.     public boolean interpret(Context ctx) {  
    38.         return ctx.lookup(this);  
    39.     }  
    40.   
    41. }  


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

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:10:55 
    6.  *  
    7.  * @类说明 :代表逻辑“与”操作的And类,表示由两个布尔表达式通过逻辑“与”操作给出一个新的布尔表达式的操作 
    8.  */  
    9. public class And extends Expression {  
    10.   
    11.     private Expression left, right;  
    12.   
    13.     public And(Expression left, Expression right) {  
    14.         this.left = left;  
    15.         this.right = right;  
    16.     }  
    17.   
    18.     @Override  
    19.     public boolean equals(Object obj) {  
    20.         if (obj != null && obj instanceof And) {  
    21.             return left.equals(((And) obj).left) && right.equals(((And) obj).right);  
    22.         }  
    23.         return false;  
    24.     }  
    25.   
    26.     @Override  
    27.     public int hashCode() {  
    28.         return this.toString().hashCode();  
    29.     }  
    30.   
    31.     @Override  
    32.     public boolean interpret(Context ctx) {  
    33.   
    34.         return left.interpret(ctx) && right.interpret(ctx);  
    35.     }  
    36.   
    37.     @Override  
    38.     public String toString() {  
    39.         return "(" + left.toString() + " AND " + right.toString() + ")";  
    40.     }  
    41.   
    42. }  


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

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:11:20 
    6.  *  
    7.  * @类说明 :代表逻辑“或”操作的Or类,代表由两个布尔表达式通过逻辑“或”操作给出一个新的布尔表达式的操作 
    8.  */  
    9. public class Or extends Expression {  
    10.     private Expression left, right;  
    11.   
    12.     public Or(Expression left, Expression right) {  
    13.         this.left = left;  
    14.         this.right = right;  
    15.     }  
    16.   
    17.     @Override  
    18.     public boolean equals(Object obj) {  
    19.         if (obj != null && obj instanceof Or) {  
    20.             return this.left.equals(((Or) obj).left) && this.right.equals(((Or) obj).right);  
    21.         }  
    22.         return false;  
    23.     }  
    24.   
    25.     @Override  
    26.     public int hashCode() {  
    27.         return this.toString().hashCode();  
    28.     }  
    29.   
    30.     @Override  
    31.     public boolean interpret(Context ctx) {  
    32.         return left.interpret(ctx) || right.interpret(ctx);  
    33.     }  
    34.   
    35.     @Override  
    36.     public String toString() {  
    37.         return "(" + left.toString() + " OR " + right.toString() + ")";  
    38.     }  
    39.   
    40. }  


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

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:11:36 
    6.  *  
    7.  * @类说明 :代表逻辑“非”操作的Not类,代表由一个布尔表达式通过逻辑“非”操作给出一个新的布尔表达式的操作 
    8.  */  
    9. public class Not extends Expression {  
    10.   
    11.     private Expression exp;  
    12.   
    13.     public Not(Expression exp) {  
    14.         this.exp = exp;  
    15.     }  
    16.   
    17.     @Override  
    18.     public boolean equals(Object obj) {  
    19.         if (obj != null && obj instanceof Not) {  
    20.             return exp.equals(((Not) obj).exp);  
    21.         }  
    22.         return false;  
    23.     }  
    24.   
    25.     @Override  
    26.     public int hashCode() {  
    27.         return this.toString().hashCode();  
    28.     }  
    29.   
    30.     @Override  
    31.     public boolean interpret(Context ctx) {  
    32.         return !exp.interpret(ctx);  
    33.     }  
    34.   
    35.     @Override  
    36.     public String toString() {  
    37.         return "(Not " + exp.toString() + ")";  
    38.     }  
    39.   
    40. }  


     

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

     
    1. package com.bankht.Interpreter;  
    2.   
    3. import java.util.HashMap;  
    4. import java.util.Map;  
    5.   
    6. /** 
    7.  * @author: 特种兵—AK47 
    8.  * @创建时间:2012-7-3 下午03:11:54 
    9.  *  
    10.  * @类说明 :环境(Context)类定义出从变量到布尔值的一个映射 
    11.  */  
    12. public class Context {  
    13.   
    14.     private Map<Variable, Boolean> map = new HashMap<Variable, Boolean>();  
    15.   
    16.     public void assign(Variable var, boolean value) {  
    17.         map.put(var, new Boolean(value));  
    18.     }  
    19.   
    20.     public boolean lookup(Variable var) throws IllegalArgumentException {  
    21.         Boolean value = map.get(var);  
    22.         if (value == null) {  
    23.             throw new IllegalArgumentException();  
    24.         }  
    25.         return value.booleanValue();  
    26.     }  
    27. }  


      client类

     
    1. package com.bankht.Interpreter;  
    2.   
    3. /** 
    4.  * @author: 特种兵—AK47 
    5.  * @创建时间:2012-7-3 下午03:12:17 
    6.  *  
    7.  * @类说明 :client类 
    8.  */  
    9. public class Client {  
    10.   
    11.     public static void main(String[] args) {  
    12.         Context ctx = new Context();  
    13.         Variable x = new Variable("x");  
    14.         Variable y = new Variable("y");  
    15.         Constant c = new Constant(true);  
    16.         ctx.assign(x, false);  
    17.         ctx.assign(y, true);  
    18.   
    19.         Expression exp = new Or(new And(c, x), new And(y, new Not(x)));  
    20.         System.out.println("x=" + x.interpret(ctx));  
    21.         System.out.println("y=" + y.interpret(ctx));  
    22.         System.out.println(exp.toString() + "=" + exp.interpret(ctx));  
    23.     }  
    24.   
    25. }  


      执行结果例如以下:

     

    x=false  

    y=true  

    ((true AND x) OR (y AND (Not x)))=true  

     

     

    四、优缺点

    解释器模式提供了一个简单的方式来运行语法,并且easy改动或者扩展语法。

    一般系统中非常多类使用相似的语法,能够使用一个解释器来取代为每个规则实现一个解释器。并且在解释器中不同的规则是由不同的类来实现的,这样使得加入一个新的语法规则变得简单。

    可是解释器模式对于复杂文法难以维护。能够想象一下。每个规则要相应一个处理类,并且这些类还要递归调用抽象表达式角色,多如乱麻的类交织在一起是多么恐怖的一件事啊。

    五、总结

    这样对解释器模式应该有了些大体的认识了吧。因为这个模式使用的案例匮乏。所以本文大部分观点直接来自于GOF的原著。仅仅是实例代码是亲自实现并调试通过的。

    本文借鉴:

    http://www.cnblogs.com/jingmoxukong/p/4236961.html

    http://blog.csdn.net/hfmbook/article/details/7688593

    http://blog.csdn.net/ylchou/article/details/7594135

    http://blog.csdn.net/m13666368773/article/details/7712110

     

     

  • 相关阅读:
    笨蛋蛋都能学会的开机grub消除(双系统开机总是黑屏肿么办--多半是欠reset)
    Find a way HDU
    非常可乐 HDU
    Oil Deposits HDU
    迷宫问题 POJ
    Fire!
    Fire Game FZU
    Pots POJ
    Prime Path POJ
    Jquery鼠标悬停按钮图标动态变化效果
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6940025.html
Copyright © 2020-2023  润新知