设计模式之解释器模式(Interpreter)

时间:2022-03-15 17:06:13
意图: 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.
适用性: 1.该文法简单对于复杂的文法,文法的类层次变得庞大而无法管理.此时语法分析程序生成器 这样的工具是更好的选择.它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且 还能节省时间 2.效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的,而是首先 将他们转换成另一种形式.
效果: 1.易于改变和扩展文法 2.易于实现文法 3.复杂的文法难以维护 4.增加了新的解释表达式的方式
代码实现:


package com.git.books.b_design_patterns.o_interpreter;
/**
* @Description: 解释器*接口定义类
* Expression :: Expression And Expression |
* Expression Or Expression |
* Not Expression |
* Variable |
* Constant
*
* @author: songqinghu
* @date: 2017年3月13日 下午7:40:43
* Version:1.0
*/
public interface Expression {

/***
* @描述:定义解释过程
* @author: songqinghu
*/
public boolean interpreter(Context context);


@Override
boolean equals(Object obj);

@Override
int hashCode();


@Override
String toString();

}

package com.git.books.b_design_patterns.o_interpreter;

import java.util.HashMap;
import java.util.Map;
/**
* @Description: 解释器环境类
* @author: songqinghu
* @date: 2017年3月13日 下午7:41:18
* Version:1.0
*/
public class Context {

private Map<Variable, Boolean> contexts = new HashMap<Variable, Boolean>();

public void assgin(Variable variable,Boolean flag){
contexts.put(variable, flag);
}

public boolean lookup(Variable variable){
Boolean result = contexts.get(variable);
if(result !=null){
return result;
}else{
throw new RuntimeException("the variable is not Definition" );
}
}
}

package com.git.books.b_design_patterns.o_interpreter;
/**
* @Description: 结束节点 要返回 true或者false
* @author: songqinghu
* @date: 2017年3月13日 下午7:55:22
* Version:1.0
*/
public class Constant implements Expression {

private Boolean constant;

public Constant(Boolean constant) {
this.constant = constant;
}


@Override
public boolean interpreter(Context context) {
return constant;
}

@Override
public boolean equals(Object obj) {

if(obj !=null && obj instanceof Constant){
return constant == ((Constant) obj).constant;
}
return false;
}

@Override
public int hashCode() {

return this.toString().hashCode();
}

@Override
public String toString() {
return constant.toString();
}
}

package com.git.books.b_design_patterns.o_interpreter;

public class Variable implements Expression {

private String name;

public Variable(String name) {
this.name = name;
}

@Override
public boolean interpreter(Context context) {

return context.lookup(this);
}

@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.toString();
}

}

package com.git.books.b_design_patterns.o_interpreter;

public class And implements Expression {

private Expression left;

private Expression right;

public And(Expression left,Expression right) {
this.left = left;
this.right = right;
}


@Override
public boolean interpreter(Context context) {
return left.interpreter(context) && right.interpreter(context);
}

@Override
public boolean equals(Object obj) {
if(obj !=null && obj instanceof And){
return this.left.equals(((And)obj).left) && this.right.equals(((And)obj).right);
}
return false;
}


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


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



}

package com.git.books.b_design_patterns.o_interpreter;

public class Or implements Expression {

private Expression left;

private Expression right;

public Or(Expression left,Expression right) {
this.left = left;
this.right = right;
}

@Override
public boolean interpreter(Context context) {
return left.interpreter(context) || right.interpreter(context);
}

@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 String toString() {
return " ("+left.toString() +" Or " + right.toString() + ") ";
}



}

package com.git.books.b_design_patterns.o_interpreter;

public class Not implements Expression {

private Expression exp;

public Not(Expression exp) {
this.exp = exp;
}

@Override
public boolean interpreter(Context context) {
return ! exp.interpreter(context);
}

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


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


@Override
public String toString() {
return " (Not "+exp.toString() +") ";
}


}

package com.git.books.b_design_patterns.o_interpreter;

public class ExpressionClient {

public static void main(String[] args) {

Context context = new Context();
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
context.assgin(a, true);
context.assgin(b, false);
context.assgin(c, false);

Or result = new Or(new And(new Not(new Or(new Constant(true), a)), new Or(new Not(b), c)), new And(new Or(a, b), c));


System.out.print(result.toString());
System.out.print(" = ");
System.out.println(result.interpreter(context));




}
}


运行结果:
( ( (Not (true Or a) ) And ( (Not b) Or c) ) Or ( (a Or b) And c) ) = false

结构图:

设计模式之解释器模式(Interpreter)



重点: 理解解释器如何定义文法和解释文法.
参考: <<设计模式>> <<Java与模式>>