细说模板名称
提示:
博主:章飞 _906285288的博客
博客地址:http://blog.csdn.net/qq_29924041
细说解释器模式
解释器模式,说句实话 ,我真的不是特别想写这个解释器模式,因为这玩意理解起来虽然不难,但是在实际应用中还是比较难的,算是在设计模式中比较难的一类设计模式。应用场景从目前开发来看,应用并不是那么的广泛,所以简单扯扯。
定义
解释器模式:就是按照一定的语法和规则进行解析的方案。给定一门语言,定义它的文法,并定义一个解释器对原来的语法进行解释
其实解释器就是翻译机而已,但是语法和逻辑复杂啊
UML模型
从图上看其实解释器模式好像也没什么元素内容:
1:AbstractExpression抽象的解释器,具体的解释任务由各个子类进行实现
2:TerminalExpression终结符解释器,每个解释器都要有终结符号的啊,不然怎么知道翻译结束了呢
3:NonterminalExpression 非终结符解释器,每个语法规则对应的非终结语法
4:Context 环境角色
基于UML的代码
package src.com.zzf.designpattern.interpreterpattern.demo2;
/**
* 抽象解释器,具体的解释任务由各个实现类来完成,
* @author Administrator
*
*/
public abstract class AbstractExpression {
public abstract Object interpreter(Context ctx);
}
package src.com.zzf.designpattern.interpreterpattern.demo2;
import src.com.zzf.designpattern.interpreterpattern.demo1.Expression;
/**
* 非终结符表达式
* @author Administrator
*
*/
public class NonterminalExpression extends AbstractExpression{
public NonterminalExpression(Expression ...expressions){
}
@Override
public Object interpreter(Context ctx) {
// TODO Auto-generated method stub
return null;
}
}
package src.com.zzf.designpattern.interpreterpattern.demo2;
/**
* 终结符表达式,通常只有一个,但是可以对应多个对象
* @author Administrator
*
*/
public class TerminalExpression extends AbstractExpression {
@Override
public Object interpreter(Context ctx) {
// TODO Auto-generated method stub
return null;
}
}
package src.com.zzf.designpattern.interpreterpattern.demo2;
import java.util.Stack;
import src.com.zzf.designpattern.interpreterpattern.demo1.Expression;
public class Context {
public static void main(String[] args) {
Context ctx = new Context();
Stack<Expression> stack = null;
for(;;){
//进行语法填充
}
Expression exp = stack.pop();
exp.interpreter(ctx);
}
}
可以看到起其uml的代码其实没有任何run的意义,其实解释器模式确实是一种思想,就是如果结合语法翻译规则翻译出正确的结果。
最最重要的是分析语法规则的共性与特性,然后才能解释
场景一
场景
照搬设计模式之禅中的四则运算
代码
package src.com.zzf.designpattern.interpreterpattern.demo1;
import java.util.HashMap;
/**
* 抽象的解释器
* @author zhouzhangfei
*
*/
public abstract class Expression {
public abstract int interperter(HashMap<String, Integer> var);
}
package src.com.zzf.designpattern.interpreterpattern.demo1;
import java.util.HashMap;
/**
* 变量解释器
* @author Administrator
*
*/
public class VarExpression extends Expression {
private String key;
public VarExpression(String key){
this.key = key;
}
@Override
public int interperter(HashMap<String, Integer> var) {
// TODO Auto-generated method stub
return var.get(key);
}
}
package src.com.zzf.designpattern.interpreterpattern.demo1;
/**
* 抽象的符号解释器
* @author zhouzhangfei
*
*/
public abstract class SymbolExpression extends Expression{
protected Expression left;
protected Expression right;
//所有的解析公式都只关心自己左右两个表达式的结果
public SymbolExpression(Expression _left,Expression _right){
this.left = _left;
this.right = _right;
}
}
package src.com.zzf.designpattern.interpreterpattern.demo1;
import java.util.HashMap;
/**
* 加法解释器
* @author zhouzhangfei
*
*/
public class AddExpression extends SymbolExpression{
public AddExpression(Expression _left,Expression _right){
super(_left,_right);
}
@Override
public int interperter(HashMap<String, Integer> var) {
// TODO Auto-generated method stub
return super.left.interperter(var) + super.right.interperter(var);
}
}
package src.com.zzf.designpattern.interpreterpattern.demo1;
import java.util.HashMap;
/**
* 减法解释器
* @author zhouzhangfei
*
*/
public class DeleteExpression extends SymbolExpression{
public DeleteExpression(Expression _left, Expression _right) {
super(_left, _right);
// TODO Auto-generated constructor stub
}
@Override
public int interperter(HashMap<String, Integer> var) {
// TODO Auto-generated method stub
return super.left.interperter(var) - super.right.interperter(var);
}
}
运算器
package src.com.zzf.designpattern.interpreterpattern.demo1;
import java.util.HashMap;
import java.util.Stack;
public class Calculator {
private Expression expression;
public Calculator(String expStr){
Stack<Expression> stack = new Stack<Expression>();
char[] charArray = expStr.toCharArray();
Expression left = null;
Expression right = null;
for(int i=0;i<charArray.length;i++){
switch(charArray[i]) {
case '+':
left = stack.pop();
right=new VarExpression(String.valueOf(charArray[++i]));
stack.push(new AddExpression(left,right));
break;
case '-':
left = stack.pop();
right=new VarExpression(String.valueOf(charArray[++i])) ;
stack.push(new DeleteExpression(left,right));
break;
default: //
stack.push(new VarExpression(String.valueOf(charArray[i])));
}
}
this.expression = stack.pop();
}
public int run(HashMap<String,Integer> var){
return this.expression.interperter(var);
}
}
package src.com.zzf.designpattern.interpreterpattern.demo1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
public class Client {
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
HashMap<String, Integer> var = getValue(expStr);
Calculator cal = new Calculator(expStr);
System.out.println("" + expStr + "=" + cal.run(var));
}
public static String getExpStr() throws IOException {
System.out.print("请输入");
return new BufferedReader(new InputStreamReader(System.in)).readLine();
}
//
public static HashMap<String,Integer> getValue(String exprStr) throws IOException{
HashMap<String,Integer> map = new HashMap<String,Integer>();
for(char ch:exprStr.toCharArray()){
if(ch != '+' && ch != '-'){
if(!map.containsKey(String.valueOf(ch))){
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch),Integer.valueOf(in));
}
}
}
return map;
}
}
解释器模式应用和注意事项
解释器模式其实是一个简单语法的分析工具,具有良好的扩展性,但是如果要去解析一系列复杂语法的时候,这个时候解释器模式可能会出现类似类膨胀,再由于解释器模式其实使用的递归等,所以很容易引发一些效率上的问题。所以其在实际的开发过程中是比较少用的,但是还是很有必要进行了解,毕竟在某些业务场景下还是有可能会使用到的。再加上其思想的先进性。
欢迎继续访问,我的博客