目录
- 定义
- 模式结构
- 角色职责
- 代码实现
- 场景适用
- 优缺点
定义
解释器模式(Interpreter Pattern) 提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等,是一种类行为型模式。
模式结构
角色职责
1.环境角色(Context): 用来存储解释器的上下文环境,包含解释器之外的一些全局信息,比如需要解释的文法等。
2.客户端(Client): 解释器的客户端,通常在这里将按照语言的语法做的表达式转换成为使用解释器对象描述的抽象语法树,然后调用解释操作。
3.解释器抽象类(AbstractExpression): 定义解释器的接口,约定解释器的解释操作。
4.终结符表达式(TerminalExpression): 解释器具体实现类,它实现了与文法中的终结符相关联的解释操作,在句子中的每一个终结符都是该类的一个实例,通常在一个解释器模式中只有少数个终结符表达式,它们的实例可以通过非终结符表达式组成较为复杂的句子。
5.非终结符表达式(NonterminalExpression): 解释器具体实现类,它实现了文法中非终结符的解释操作,由于在非终结符表达式中可以包含终结符表达式,也可以继续包含非终结符表达式,因此解释操作一般通过递归的方式来完成。
代码实现
环境角色:
public class Context {
private String[] citys = {"韶关", "广州"};
private String[] persons = {"老人", "妇女", "儿童"};
private Expression cityPerson;
public Context() {
Expression city = new TerminalExpression(citys);
Expression person = new TerminalExpression(persons);
cityPerson = new AndExpression(city, person);
}
public void freeRide(String info) {
boolean ok = cityPerson.interpret(info);
if (ok) System.out.println("您是" + info + ",您本次乘车免费!");
else System.out.println(info + ",您不是免费人员,本次乘车扣费2元!");
}
}
解释器抽象类:
// 抽象表达式类
public interface Expression {
public boolean interpret(String info); //解释方法
}
终结表达式:
public class TerminalExpression implements Expression {
private Set<String> set = new HashSet<String>();
public TerminalExpression(String[] data) {
for (int i = 0; i < data.length; i++) set.add(data[i]);
}
public boolean interpret(String info) {
if (set.contains(info)) {
return true;
}
return false;
}
}
非终结表达式:
public class AndExpression implements Expression {
private Expression city = null;
private Expression person = null;
public AndExpression(Expression city, Expression person) {
this.city = city;
this.person = person;
}
public boolean interpret(String info) {
String s[] = info.split("的");
return city.interpret(s[0]) && person.interpret(s[1]);
}
}
客户端:
public class InterpreterPattern {
public static void main(String[] args) {
Context bus = new Context();
bus.freeRide("韶关的老人");
bus.freeRide("韶关的年轻人");
bus.freeRide("广州的妇女");
bus.freeRide("广州的儿童");
bus.freeRide("山东的儿童");
}
}
打印结果:
您是韶关的老人,您本次乘车免费!
韶关的年轻人,您不是免费人员,本次乘车扣费2元!
您是广州的妇女,您本次乘车免费!
您是广州的儿童,您本次乘车免费!
山东的儿童,您不是免费人员,本次乘车扣费2元!
场景适用
1.可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
2.一些重复出现的问题可以用一种点单的语言来进行表达。
3.文法较为简单,对于复杂的文法,解释器模式中的文法类层次结构将变得很庞大而无法管理,此时最好使用语法分析程序生成器。
4.效率不是关键问题,最高效的解释器通常不是通过直接解释语法分析树来实现的,而是需要将它们转换成另一种形式,使用解释器模式的执行效率并不高。
优缺点
优点:
1.易于改变和扩展文法,由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承机制来改变和扩展文法,实现简单语言方便。
2.易于实现文法,在抽象语法树中每一个节点类的实现方式都是相似的,这些类的编写都不是很复杂,它们还可以通过一些工具自动生成。
3.增加了新的解释表达式的方式,解释器模式可以让用户较为方便的增加新类型的表达式,增加新的表达式时无需对现有的表达式进行修改,符合开闭原则。
缺点:
1.对于复杂文法难以维护,在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,则可能难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。
2.执行效率较低,由于解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢。
3.应用场景很有限,在软件开发中很少需要自定义文法规则,因此该模式的使用频率很低,在一班的软件中难以找到其应用实例,导致理解和使用该模式的难度较大。