目录
说明
- 行为型模式之一,其他还有命令模式、模板方法模式、访问者模式、观察者模式、中介者模式、备忘录模式、迭代器模式、状态模式、策略模式、职责链模式(责任链模式)
-
解释器模式( Interpreter Pattern ):给定一个语言 ( 表达式 ) ,定义它的文法的一种表示,并定义一个解释器,使用该解释器来解释语言中的句子( 表达式)
-
使用解释器可能带来的问题:解释器模式会引起 类膨胀、解释器模式采用递归调用方法,将会导致 调试非常复杂、效率可能降低
-
如果一个特定类型的问题发生的频率足够高,那么可能值得为该问题的各个实例表述为一个简单语言的句子。这样就可以构建一个解释器,通过解释这些句子来解决问题。
实现方式
以加减乘除为例
public class InterpreterTest {
public static void main(String[] args) {
Context context = new Context();
// 变量赋值
context.addValue("a", 6);
context.addValue("b", 9);
context.addValue("c", 1);
// 创建变量(终结表达式)
Variable a = new Variable("a");
Variable b = new Variable("b");
Variable c = new Variable("c");
// 先拼接表达式
// a×b
AbstractExpression multiplyValue = new Multiply(a, b);
// a-b+c
AbstractExpression addValue = new Add(new Subtract(a, b), c);
// (a*b)/(a-b+c)
AbstractExpression divisionValue = new Division(multiplyValue, addValue);
// 展示变量以及代表的值
System.out.println(context.getValueMap());
// 展示将表达式解释出来的结果
System.out.println("(a*b)/(a-b+c) = " + divisionValue.interpreter(context));
}
}
/**
* 抽象解释器
* <p>
*
* @author : ZRH
* @version : 1.0.0
* @date : 2020-07-24
*/
abstract class AbstractExpression {
/**
* 解释结果
* <p>
*
* @param context
* @return java.lang.Integer
* @author : ZRH
* @version : 1.0.0
* @date : 2020-07-24
*/
public abstract Integer interpreter(Context context);
}
/**
* 非终结表达式:加法
* <p>
*
* @author ZRH
* @version 1.0.0
* @date 2020/7/24
*/
class Add extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public Add(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public Integer interpreter(Context context) {
return left.interpreter(context) + right.interpreter(context);
}
}
/**
* 非终结表达式:减法
* <p>
*
* @author ZRH
* @version 1.0.0
* @date 2020/7/24
*/
class Subtract extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public Subtract(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public Integer interpreter(Context context) {
return left.interpreter(context) - right.interpreter(context);
}
}
/**
* 非终结表达式:乘法
* <p>
*
* @author ZRH
* @version 1.0.0
* @date 2020/7/24
*/
class Multiply extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public Multiply(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public Integer interpreter(Context context) {
return left.interpreter(context) * right.interpreter(context);
}
}
/**
* 非终结表达式:除法
* <p>
*
* @author ZRH
* @version 1.0.0
* @date 2020/7/24
*/
class Division extends AbstractExpression {
private final AbstractExpression left;
private final AbstractExpression right;
public Division(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
@Override
public Integer interpreter(Context context) {
int right = this.right.interpreter(context);
if (right != 0) {
return left.interpreter(context) / right;
}
return -1;
}
}
/**
* 终结表达式:变量
* <p>
*
* @author ZRH
* @version 1.0.0
* @date 2020/7/24
*/
class Variable extends AbstractExpression {
private final String key;
public Variable(String key) {
this.key = key;
}
@Override
public Integer interpreter(Context context) {
return context.getValue(key);
}
}
/**
* 环境上下文
* <p>
*
* @author ZRH
* @version 1.0.0
* @date 2020/7/24
*/
class Context {
/**
* 存储变量以及代表的值,比如a = 3
*/
private final Map<String, Integer> valueMap = new HashMap<>();
public Map<String, Integer> getValueMap() {
return valueMap;
}
public void addValue(final String key, final int value) {
valueMap.put(key, Integer.valueOf(value));
}
public int getValue(final String key) {
return valueMap.get(key).intValue();
}
}
应用场景
-
将一个需要解释执行的语言中的句子表示为一个抽象语法树
-
一些重复出现的问题可以用一种简单的语言来表达
-
一个简单语法需要解释的场景
-
编译器
-
运算表达式计算
-
正则表达式
-
机器人