行为模式---之--解释器模式
解释器模式是类的行为模式,给定一个语言之后,解释器模式可以定义出其方法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。
如果某一类问题一再地发生的话,那么一个意义的做法就是将此类问题的各个实例表达为一个简单语言中的语句。这样就可以建造一个解释器,通过解释这些语句达到解决问题的目的。
模式所涉及的角色有:
1.抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个interpret()方法,称做解释操作
2.终结符表达(Terminal Expression)表达式角色:这是一个具体角色,它实现了抽象表达式角色所要求的接口,主要是一个interpret()方法。文法中的每一个终结符都有一个具体终结表达式与之相对应。
3.非终结符表达式(Nonterminal Expression)角色:这是一个具体角色。
文法中的每一条规则R=R1R2..Rn都需要一个具体的非终结符表达式类。对每一个R1R2..Rn中的符号都持有一个静态类型为Expression的实例变量。实现解释操作,即interpret()方法。解释操作以递归方式调用上面所提到的代表R1R2..Rn中的各个符号的实例变量。
4.客户端(Client)角色:代表模式的客户端它有以下功能:
建造一个抽象语法树
调用解释操作(interpret())
在一般情况下,模式还需要一个环境角色:
5.环境(Context)角色:提供解释器之外的一些全局信息,比如变量的真实量值
这个例子模仿Java语言中对布尔表达式进行操作和求值。
1 public class Client { 2 private static Context ctx; 3 private static Expression exp; 4 public static void main(String[] args) { 5 ctx = new Context(); 6 Variable x = new Variable("x"); 7 Variable y = new Variable("y"); 8 Constant c = new Constant(true); 9 ctx.assign(x, false); 10 ctx.assign(y, true); 11 exp = new Or(new And(c,x),new And(y,new Not(x))); 12 System.out.println("x = "+x.interpret(ctx)); 13 System.out.println("y = "+y.interpret(ctx)); 14 System.out.println(exp.toString()+"=" +exp.interpret(ctx)); 15 } 16 } 17 18 //抽象角色Expression 19 /* 20 * 这个抽象类代表终结类和非终结类的抽象化 21 * 其中终结类和非终结类来自下面的文法 22 * Expression ::= 23 * Expression AND Expression 24 * |Expression OR Expression 25 * |NOT Expression 26 * |Variable 27 * |Constant 28 * Variable ::=...//可以打印出的非空白字符串 29 * Contant ::="true"|"false" 30 */ 31 abstract class Expression{ 32 //以环境类为准,本方法解释给定的任何一个表达式 33 public abstract boolean interpret(Context ctx); 34 //检验两个表达式在结构上是否相同 35 public abstract boolean equals(Object o); 36 //返回表达式的hashcode 37 public abstract int hashCode(); 38 //将表达式转换成字符串 39 public abstract String toString(); 40 } 41 42 //Constant类,通过构造子传入一个布尔常量,得到一个包装了这个布尔常量的对象,new Constant(true) 43 class Constant extends Expression{ 44 45 private boolean value; 46 //构造子 47 public Constant(boolean value){ 48 this.value = value; 49 } 50 //解释操作 51 @Override 52 public boolean interpret(Context ctx) { 53 return value; 54 } 55 //检验两个表达式是否相同 56 @Override 57 public boolean equals(Object o) { 58 if(o!=null&&o instanceof Constant){ 59 return this.value = ((Constant)o).value; 60 } 61 return false; 62 } 63 64 @Override 65 public int hashCode() { 66 return (this.toString()).hashCode(); 67 } 68 69 @Override 70 public String toString() { 71 return new Boolean(value).toString(); 72 } 73 74 } 75 //Variable类 使用时将变量名传入构造子中,如new Variable("x")就声明了一个名字为x的变量 76 class Variable extends Expression{ 77 private String name; 78 79 public Variable(String name){ 80 this.name = name; 81 } 82 //解释操作 83 @Override 84 public boolean interpret(Context ctx) { 85 try { 86 return ctx.lookup(this); 87 } catch (Exception e) { 88 e.printStackTrace(); 89 } 90 return false; 91 } 92 93 @Override 94 public boolean equals(Object o) { 95 if(o!=null&&o instanceof Variable){ 96 return this.name.equals(((Variable)o).name); 97 } 98 return false; 99 } 100 101 //返回hashcode 102 @Override 103 public int hashCode() { 104 return (this.toString()).hashCode(); 105 } 106 107 //将表达式转换成字符串 108 @Override 109 public String toString() { 110 return name; 111 } 112 } 113 //And类 new And(x,y)代表x And y 114 class And extends Expression{ 115 116 private Expression left,right; 117 public And(Expression left,Expression right){ 118 this.left = left; 119 this.right = right; 120 } 121 //解释操作 122 @Override 123 public boolean interpret(Context ctx) { 124 return left.interpret(ctx)&&right.interpret(ctx); 125 } 126 127 @Override 128 public boolean equals(Object o) { 129 if(o!=null&&o instanceof And){ 130 return this.left.equals(((And)o).left)&&this.right.equals(((And)o).right); 131 } 132 return false; 133 } 134 135 @Override 136 public int hashCode() { 137 return this.toString().hashCode(); 138 } 139 //将表达式转换成字符串 140 @Override 141 public String toString() { 142 return "("+left.toString()+"AND"+right.toString()+")"; 143 } 144 145 } 146 //Or类 147 class Or extends Expression{ 148 149 private Expression left,right; 150 public Or(Expression left,Expression right){ 151 this.left = left; 152 this.right = right; 153 } 154 //解释操作 155 @Override 156 public boolean interpret(Context ctx) { 157 return left.interpret(ctx)&&right.interpret(ctx); 158 } 159 160 @Override 161 public boolean equals(Object o) { 162 if(o!=null&&o instanceof And){ 163 return this.left.equals(((Or)o).left)&&this.right.equals(((Or)o).right); 164 } 165 return false; 166 } 167 168 @Override 169 public int hashCode() { 170 return this.toString().hashCode(); 171 } 172 //将表达式转换成字符串 173 @Override 174 public String toString() { 175 return "("+left.toString()+"OR"+right.toString()+")"; 176 } 177 } 178 //Not类 179 class Not extends Expression{ 180 private Expression exp; 181 public Not(Expression exp){ 182 this.exp = exp; 183 } 184 @Override 185 public boolean interpret(Context ctx) { 186 return !exp.interpret(ctx); 187 } 188 @Override 189 public boolean equals(Object o) { 190 if(o!=null&& o instanceof Not){ 191 return this.exp.equals(((Not)o).exp); 192 } 193 return false; 194 } 195 @Override 196 public int hashCode() { 197 return this.toString().hashCode(); 198 } 199 @Override 200 public String toString() { 201 return "(Not" + exp.toString() +")"; 202 } 203 } 204 205 //Context 206 class Context{ 207 private HashMap map = new HashMap(); 208 public void assign(Variable var,boolean value){ 209 map.put(var, new Boolean(value)); 210 } 211 public boolean lookup(Variable var)throws Exception{ 212 Boolean value = (Boolean)map.get(var); 213 if(value ==null){ 214 throw new Exception(); 215 } 216 return value.booleanValue(); 217 } 218 }
解释器模式适用于以下情况:
1.系统有一个简单的语言可供解释
2.一些重复发生的问题可以用这种简单的语言表达
3.效率不是主要考虑