解释器模式(INTERPRETER),通过面向对象的方式构造语言解释器,并使用该解释器按照一定的文法解释语言中的句子,属于类行为模式。记得大学时候参加过机器人足球比赛,通过面板输入指令"up move 10 and left run 8",足球机器人就会执行相应的动作。将这些指令组合就能完成高难度的射门,躲避,可谓智能也!下面将通过机器人指令解释来阐述解释器模式的强大。
一、使用场景
1、当有一个语言需要解释执行,并能从该语言的句子中抽象出语法树时,比如机器人足球比赛的指令,也就up,down,move等有限的基础操作码。
2、抽象出的文法要简单,不至于导致文法的类层次过于庞大而无法管理。对于复杂的文法可以使用语法分析程序生成器,这样无需构造抽象语法树,节省时间和空间。
3、效率不是关键的情况。高效的解释器通常不采用直接解释抽象语法树实现,而是通过转换其他形式实现,比如状态机。
二、UML图

三、Java实现
package study.patterns.interpreter;
import java.util.Stack;
/**
* 解释器模式,用面向对象的方法构造简单的语言解释器。
* 示例:使用解释器模式实现机器人指令的解析。
* 指令文法:
* expression ::= direction action distance | composite //表达式
* composite ::= expression 'and' expression //复合表达式
* direction ::= 'up' | 'down' | 'left' | 'right' //移动方向
* action ::= 'move' | 'run' //移动方式
* distance ::= an integer //移动距离
* 终结符表达式:direction、action和distance,语言的最小组成单位,不能再拆分。
* 非终结符表达式:expression和composite,完整的句子,包含一系列终结符或非终结符。
* 抽象语法树:将指令按照语法抽象为树形结构(可以使用栈模拟),是简单句子解释的重要步骤。
* @author qbg
*/
public class InterpreterPattern {
public static void main(String[] args) {
String sentence = "up move 8 and right run 10 and left move 6";//输入指令要严格按照文法
InstructionHandler handler = new InstructionHandler();
handler.handle(sentence);//抽象语法树
System.out.println(handler.interpret());//解释输入指令并输出
}
}
/**
* 抽象表达式,可以采用接口或抽象类实现
*/
interface INode{
public String interpret();
}
/**
* And解释,用于将两个表达式进行and操作,非终止表达式
*/
class AndNode implements INode{
private INode left;//and的左表达式
private INode right;//and的右表达式
public AndNode(INode left,INode right){
this.left = left;
this.right = right;
}
/**
* And表达式解释操作,两个操作的联合
*/
@Override
public String interpret() {
return left.interpret()+"再"+right.interpret();
}
}
/**
* 简单的句子解释,由基本的原子解释组成,句子解释可以组合成复杂的句子
*/
class SentenceNode implements INode{
private INode direction;//方向解释
private INode action;//动作解释
private INode distance;//距离解释
public SentenceNode(INode direction,INode action,INode distance){
this.direction = direction;
this.action = action;
this.distance = distance;
}
/**
* 简单句子解释逻辑,将原子解释按规则解释就行(必须按文法规则,否则解释出错)
*/
@Override
public String interpret() {
return direction.interpret()+action.interpret()+distance.interpret();
}
}
/**
* 方向解释,解释方向操作码(up,down,left,right)并执行相应操作,终结符表达式。
*/
class DirectionNode implements INode{
private String direction;
public DirectionNode(String direction){
this.direction = direction;
}
/**
* 方向表达式的解释操作
*/
@Override
public String interpret() {
if(direction.equalsIgnoreCase("up")){
return "向上";
}else if(direction.equalsIgnoreCase("down")){
return "向下";
}else if(direction.equalsIgnoreCase("left")){
return "向左";
}else if(direction.equalsIgnoreCase("right")){
return "向右";
}else{
return "无效操作码";
}
}
}
/**
* 动作解释,解释操作码(move,run)并执行相应操作,终结符表达式
*/
class ActionNode implements INode{
private String action;
public ActionNode(String action){
this.action = action;
}
/**
* 动作表达式的解释操作
*/
@Override
public String interpret() {
if(action.equalsIgnoreCase("move")){
return "移动";
}else if(action.equalsIgnoreCase("run")){
return "快速移动";
}else{
return "无效操作码";
}
}
}
/**
* 距离解释,用于解释移动的距离,数字,终结符表达式。
*/
class DistanceNode implements