十五、解释器模式Interpreter(行为型)

时间:2021-07-27 17:11:35

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过这些句子来解决该问题。例如正则表达式就是一种描述字符串模式的一种标准语言。解释器模式描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。在解释器模式中,会使用类来表示一条文法规则。

十五、解释器模式Interpreter(行为型)

public interface AbstractExpressioon {}
public interface TerminalExpression extends AbstractExpressioon{}
public interface NonTerminalExpression extends AbstractExpressioon{}
public class Context {
/**
* NotExp = VariableExp | Not |'('NotExp')'
* Not = 'not' NotExp
* VariableExp = 'A' | 'B' | 'C' | 'D' |..
* */
private Map<String, Boolean> store = new HashMap<>();

public boolean lookUp(String name) {
return store.get(name);
}

public void assign(VariableExp var, boolean val) {
store.put(var.getName(), val);
}
}
public abstract class NotExp implements AbstractExpressioon {
public abstract boolean evaluate(Context context);
}
public class VariableExp extends NotExp implements TerminalExpression {
private String name = null;

public VariableExp(String name) {
this.name = name.toUpperCase();
}

public String getName() {
return name;
}

@Override
public boolean evaluate(Context context) {
return context.lookUp(name);
}
}
public class Not extends NotExp implements NonTerminalExpression {

private NotExp exp = null;

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

@Override
public boolean evaluate(Context context) {
return !exp.evaluate(context);
}
}
public class Client {
@Test
public void test() {
Context context = new Context();

VariableExp x = new VariableExp("x");
VariableExp y = new VariableExp("y");

context.assign(x, true);
context.assign(y, false);

NotExp exp1 = new Not(new Not(x));
NotExp exp2 = new Not(new Not(y));

System.out.println(exp1.evaluate(context));
System.out.println(exp2.evaluate(context));
}
}

上面描述的接口定义的是一种类型,AbstractExpressioon定义的是解释器模式的基础类,表示所有的表达式类型,TerminalExpression和NonTerminalExpression表示是基础表达式类型还是复合表达式。NotExp系统的只是单纯实现了非逻辑的表达式的处理,这个系统中没有对表达式解析的过程,只是直接使用对象关系来创建表达式。

按照书中的描述方式,这里给出NotExp系统的的文法定义:

NotExp = VariableExp | Not |'('NotExp')'
Not = 'not' NotExp
VariableExp = 'A' | 'B' | 'C' | 'D' |..

这里VariableExp是TerminalExpression类型,也就是基础表达式类型,它直接会被assign值,而Not是复合表达式,它包含的逻辑是,对表达式内的value运行非逻辑。此外这个系统中还包含着Context,它的内部存储着所有VariableExp的值。

需要额外描述的是,在最宽泛的概念下几乎每个使用复合模式的系统也都使用了解释器模式,但是一般只有在用一个类层次来定义某个语言时,才强调使用解释器模式。