设计模式笔记之解释器模式的使用

<其它设计模式介绍及案例源码下载 >

简介:解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

主要解决:给定一个文本语言,定义它的文法表示,并定义解析文本的若干个文本解释器,这些解释器使用特定文法规则标识来解释语言中的句子。

优点: 1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。

缺点: 1、可利用场景比较少。 2、对于复杂的文法比较难维护。 3、解释器模式会引起类膨胀。 4、解释器模式采用递归调用方法。

使用场景: 1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。 2、一些重复出现的问题可以用一种简单的语言来进行表达。 3、编译器、运算表达式计算。

注意该模式中的特定角色:

        AbstractExpression 抽象解释器:规范解释行为,具体的解释任务由各个实现类完成,具体的解释器由TerminalExpression和NonterminalExpression组成(案例中以ExpressionInterf和NonTerminalExpression为例)。

       TerminalExpression终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是VarExpression类,表达式中的每个终结符都在堆栈中产生了一个VarExpression对象,它是最小的语法单元

       NonterminalExpression 非终结符表达式:文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是乘除法规则分别对应到MultiplyExpression和DivisionExpression两个类。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。

       环境角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,案例中的Calculator类。

实现案例:通过表达式顶级接口ExpressionInterf规范解释行为interpret,定义终结符表达式类TerminalExpression实现表达式接口。抽象出非终结符表达式父类NonTerminalExpression实现ExpressionInterf 并在其内部声明其他表达式引用,最后根据需要的定义不同的文法规则,每条规则对应于一个非终结表达式。以乘除法的实现进行展示。

例如下:

public interface ExpressionInterf {

	public int interpret();
}
//终结符表达式,他是最小的文法规则表达式
public class TerminalExpression implements ExpressionInterf {

	String context;
	
	public TerminalExpression(String context) {
		super();
		this.context=context;
	}

	@Override
	public int interpret() {
		int paramVal=Integer.parseInt(this.context);
		return paramVal;
	}

}
//定义非终结符表达式抽象父类
public abstract class NonTerminalAbstract implements ExpressionInterf {

	public ExpressionInterf left;
	public ExpressionInterf right;
		
	public NonTerminalAbstract(ExpressionInterf left, ExpressionInterf right) {
		super();
		this.left = left;
		this.right = right;
	}

}
//非终结符表达式之乘法表达式
public class MultiplyExpression extends NonTerminalAbstract {

	public MultiplyExpression(ExpressionInterf left, ExpressionInterf right) {
		super(left, right);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int interpret() {
		int ret=super.left.interpret()*super.right.interpret();
		return ret;
	}

}
//非终结符表达式之除法表达式
public class DivisionExpression extends NonTerminalAbstract {

	public DivisionExpression(ExpressionInterf left, ExpressionInterf right) {
		super(left, right);
		// TODO Auto-generated constructor stub
	}

	@Override
	public int interpret() {
		int ret=super.left.interpret()/super.right.interpret();
		return ret;
	}

}
//环境类
public class Calculator {

	ExpressionInterf exp;

	public Calculator(String param) {
		
		String[] strArrays=param.split(" ");
		ExpressionInterf left=null;
		ExpressionInterf right=null;
		Stack stack=new Stack();
		for(int i=0;i<strArrays.length;i++) {
			String value=strArrays[i];
			if("*".equalsIgnoreCase(value)) {
				left=(ExpressionInterf) stack.pop();
				right=new TerminalExpression(strArrays[++i]);
				stack.push(new MultiplyExpression(left,right));
			} else if("/".equalsIgnoreCase(value)) {
				left=(ExpressionInterf) stack.pop();
				right=new TerminalExpression(strArrays[++i]);
				stack.push(new DivisionExpression(left,right));
			} else {
				stack.push(new TerminalExpression(value));
			}
		}
		this.exp=(ExpressionInterf) stack.pop();
	}
	
	public int run() {
		return exp.interpret();
	}
}
//测试类
public class TestClass {

	public static void main(String[] args) {
		Calculator calculator=new Calculator("4 * 5 * 8 * 8");
		int ret=calculator.run();
		System.out.println(ret);
	}

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值