设计模式初探-解释器模式(一)

2014-11-24 03:00:02 · 作者: · 浏览: 0

解释器模式(INTERPRETER),通过面向对象的方式构造语言解释器,并使用该解释器按照一定的文法解释语言中的句子,属于类行为模式。记得大学时候参加过机器人足球比赛,通过面板输入指令"up move 10 and left run 8",足球机器人就会执行相应的动作。将这些指令组合就能完成高难度的射门,躲避,可谓智能也!下面将通过机器人指令解释来阐述解释器模式的强大。

一、使用场景

1、当有一个语言需要解释执行,并能从该语言的句子中抽象出语法树时,比如机器人足球比赛的指令,也就up,down,move等有限的基础操作码。

2、抽象出的文法要简单,不至于导致文法的类层次过于庞大而无法管理。对于复杂的文法可以使用语法分析程序生成器,这样无需构造抽象语法树,节省时间和空间。

3、效率不是关键的情况。高效的解释器通常不采用直接解释抽象语法树实现,而是通过转换其他形式实现,比如状态机。

二、UML图

解释器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