- 什么是解释器模式
- 解释器模式的例子
- 解释器模式的优缺点
- 解释器模式的使用场景
- 闲言碎语
什么是解释器模式
在我们我们编程或日常生活中.我们都是在使用自然语言.但是,对于电脑或计算器这种东西,他并不认识我们的自然语言.而是需要借助其他的工具将其转换为机器识别的二进制才可以被其处理.同样,再编程中我们也需要处理类似的内容.比如对日志进行分析之类的.这时我们就需要用到解释器模式了!
定义:解释器模式定义语言的文法,并且建立一个解释器来解释该语言中的句子。它属于类的行为模式。这里的语言意思是使用规定格式和语法的代码。
角色:
抽象表达式角色(AbstractExpression): 声明一个抽象的解释操作,这个接口为所有具体表达式角色都要实现的.
终结符表达式角色(TerminalExpression): 实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表达式,但有多个实例对应不同的终结符.
非终结符表达式角色(NonterminalExpression): 文法中的每条规则对应于一个非终结表达式, 非终结表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式.
环境角色(Context): 包含解释器之外的一些全局信息.
UML:
解释器模式的例子
解释器的接口
package com.designPattern.Interpreter6;
/**
* 解释器的接口
*
* @author jason
*
*/
public interface Expression {
// 解释器的方法
public int interpret(Context context);
}
解释器容器
package com.designPattern.Interpreter6;
/**
* 解释器运行的环境
*
* @author jason
*
*/
public class Context {
int num1;
int num2;
public int getNum1() {
return num1;
}
public void setNum1(int num1) {
this.num1 = num1;
}
public int getNum2() {
return num2;
}
public void setNum2(int num2) {
this.num2 = num2;
}
public Context(int num1, int num2) {
super();
this.num1 = num1;
this.num2 = num2;
}
}
具体的解释器
package com.designPattern.Interpreter6;
/**
* 具体的解释器
*
* @author jason
*
*/
public class Minus implements Expression {
@Override
public int interpret(Context context) {
// TODO Auto-generated method stub
return context.getNum1() - context.getNum2();
}
}
package com.designPattern.Interpreter6;
/**
* 具体的解释器
*
* @author jason
*
*/
public class Plus implements Expression {
@Override
public int interpret(Context context) {
return context.getNum1() + context.getNum2();
}
}
测试类
package com.designPattern.Interpreter6;
import org.junit.Test;
import junit.framework.TestCase;
/**
* 测试类
*
* @author jason
*
*/
public class InterpreterTest extends TestCase {
@Test
public void test1() {
Context context = new Context(2, 1);
Minus minus = new Minus();
assertEquals(1, minus.interpret(context));
}
@Test
public void test2() {
Context context = new Context(2, 1);
Plus plus = new Plus();
assertEquals(3, plus.interpret(context));
}
}
解释器模式的优缺点
优点:
解释器是一个简单语法分析工具,它最显著的优点就是扩展性,修改语法规则只要修改相应的非终结符表达式就可以了,若扩展语法,则只要增加非终结符类就可以了。
缺点:
解释器模式会引起类膨胀,每个语法都要产生一个非终结符表达式,语法规则比较复杂时,可能产生大量的类文件,难以维护。
解释器模式采用递归调用方法,它导致调试非常复杂。
解释器由于使用了大量的循环和递归,所以当用于解析复杂、冗长的语法时,效率是难以忍受的
解释器模式的使用场景
(1)当一个语言需要解释执行,并可以将该语言中的句子表示为一个抽象语法树的时候,可以考虑使用解释器模式(如XML文档解释、正则表达式等领域)
(2)一些重复出现的问题可以用一种简单的语言来进行表达。
(3)一个语言的文法较为简单.
(4)当执行效率不是关键和主要关心的问题时可考虑解释器模式(注:高效的解释器通常不是通过直接解释抽象语法树来实现的,而是需要将它们转换成其他形式,使用解释器模式的执行效率并不高。)
闲言碎语
尽量不要在重要模块中使用解释器模式,因为维护困难。在项目中,可以使用shell,JRuby,Groovy等脚本语言来代替解释器模式。
本例中使用的的运算比较简单,在实际中我们进行复杂的运算时还需要用到栈,前缀表达式等的知识相结合.