软件设计 解释器模式 Interpreter Pattern
作者:@kuaiquxie
作者的github:https://github.com/bitebita
本文为作者原创,如需转载,请注明出处:https://www.cnblogs.com/dzwj/p/17111649.html
解释器是一个语法分析工具,它可以识别句子语义,分离终结符号和非终结符号,提取出需要的信息,针对不同的信息做出相应的处理。其核心思想是识别语法,构建解释。
解释器模式主要包含 4 种角色:
-
抽象表达式(Expression) :负责定义解释方法
interpret
, 交由子类进行具体解释。 -
终结符表达式(Terminal Expression) :实现文法中与终结符有关的解释操作。
文法中的每一个终结符都有一个具体终结表达式与之相对应,比如公式 R = R1 + R2,R1 和 R2 就是终结符,对应的解析 R1 和 R2 的解释器就是终结符表达式。通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。
-
非终结符表达式(Nonterminal Expression):实现文法中与非终结符有关的解释操作。
文法中的每条规则都对应于一个非终结符表达式。非终结符表达式一般是文法中的运算符或者其他关键字,比如公式 R = R1 + R2 中, + 就是非终结符,解析它的解释器就是一个非终结符表达式。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。
-
上下文环境(Context) :包含解释器之外的全局信息。
它的任务一般是用来存放文法中各个终结符所对应的具体值,比如 R = R1 + R2,给 R1 赋值 100,给 R2 赋值 200,这些信息需要存放到环境中。
代码实现:
这里以根据乘客年龄和身高来判断乘坐公交车是否免费为例介绍解释器模式:
1、定义乘客
/**
* 乘客
*/
public class Passenger {
/**
* 姓名
*/
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 身高
*/
private Double height;
public Passenger(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
}
2、定义表达式
/**
* 表达式
*/
public interface Expression {
/**
* 解释年龄
* @param age 年龄
* @return 解释结果
*/
boolean interpret(int age);
/**
* 解释身高
* @param height 身高
* @return 解释结果
*/
boolean interpret(double height);
}
3、定义比较器
/**
* 比较器
*/
public enum Compare {
/**
* 较大
*/
GT,
/**
* 相等
*/
EQ,
/**
* 较小
*/
LT
}
4、定义终结符表达式
/**
* 终结符表达式
*/
public class TerminalExpression implements Expression {
/**
* 年龄
*/