第十七讲:解释器模式

学过编译原理的话应该对文法有一个理解.编译原理里面有对文法的解释.

解释器模式在程序开发不是很常用,但是也要有一个浅显的认识.如果实在不会就不用深究,暂时有个初步的认识即可.

Context就是文法,AbstractExpression是表达式解释器的一个抽象,Interpret(Context)传递的是文法的参数.解释器有两个实现类:一个是终结符的解释器,一个是非终结符的解释器.终结符的解释器比较简单.非终结符的解释器持有抽象解释器的引用,也就是说非终结符的解释器可能还持有非终结符的解释器的引用或者是终结符的解释器的引用.因为非终结符解释器它持有抽象解释器的引用.


学过编译原理的肯定知道非终结符解释器和终结符解释器的区别.非终结符解释器它可以调用其他的非终结符解释器或者说是终结符的解释器.终结符解释器比非终结符解释器简单多了.因为终结符解释器自身就可以完成对文法的解释.

如果深究去看高级的书籍.解释器模式在真正的应用开发中并不常用.解释器是分析一个文法对程序.在真正的开发中也不是特别常用.设计正则表达式的就需要对这个解释器模式进行深究.


  抽象解释器AbstractExpression是斜体的UML类图,Interpret(Context)抽象方法是斜体的UML类图里面.


 最重要的是 //对上下文环境重新进行赋值,让上下文环境保持最新的状态...否则你获得的上下文环境的值就不会增减.

 

 input和output必须同时更新,不用考虑特殊的情况.你的程序到底有几个解释器需要执行还是未知的,假设只有一个呢你那个就错误了.程序设计讲究可用性,到处都可以用.那么我不可能说为了你的那种特殊情况我还去判断你到底是第几个解释器.所以input和output同时更新,以不变应万变.


//自动递增解释器
public class PlusExpression extends Expression{

    @Override
    public void interpret(Context context) {
        // TODO Auto-generated method stub
        //提示信息
        System.out.println("自动递增");
        //获得上下文环境
        String input  =  context.getInput();
        //进行类型转换
        int intInput = Integer.parseInt(input);//把这个树转换成int类型的数据
        //就可以对它进行递增了
        //intInput++;
        ++intInput;//没有赋值的话两个表达式运行的效果是一样的.
        //intInput递增之后重新把它设置回上下文环境.
        //因为解释器不可能只有一个,你可能还有其他几个解释器.其他解释器也要对input和output进行设置.
        //对上下文环境重新进行赋值,让上下文环境保持最新的状态...否则你获得的上下文环境的值就不会增减.
        //上下文环境利用到以后必须对它进行复位.复位就是上下文环境变化了以后必须重新对上下文环境进行赋值,让它保持最新状态.
        //从上下文环境拿出一个树进行递增以后必须将它重新设置回去,这样你的递增才有效果.
        //如果你不对上下文环境进行赋值的话你仅仅是对一个方法进行赋值,方法是void的没有返回值,那么你无法知道它是否进行了递增.
        //只有对上下文环境重新赋值才可以.
        context.setInput(String.valueOf(input));//对上下文环境重新进行赋值.
        context.setOutput(intInput);//Input和Output为什么都需要进行设值,有人认为只需要设置Output(输出).
        //有人认为可以只改input不改output,不行,如果我只有一个解释器呢?追求
    }
   
}
//自动递减解释器
public class MinusExpression extends Expression{

    @Override
    public void interpret(Context context) {
        // TODO Auto-generated method stub
        System.out.println("自动递减");
        String input  = context.getInput();
        int inInput = Integer.parseInt(input);
        //inInput--;
        --inInput;
        context.setInput(String.valueOf(inInput));
        context.setOutput(inInput);
        
        
        
    }
    
} 
/**
 * 抽象解释器
 * @author zhongzh
 *
 */
public abstract class Expression {
    public abstract void interpret(Context context);//形参
}
/**
 * 上下文环境类,用来保存文法..
 * @author zhongzh
 *
 */
public class Context {
   private String input;//输入是String类型.
   private int output;//输出是int类型.
   
   
public Context(String input) {
    super();
    this.input = input;
}

public Context(int output) {
    super();
    this.output = output;
}

public Context(String input, int output) {
    super();
    this.input = input;
    this.output = output;
}
public String getInput() {
    return input;
}
public void setInput(String input) {
    this.input = input;
}
public int getOutput() {
    return output;
}
public void setOutput(int output) {
    this.output = output;
}
   
}
import java.util.ArrayList;
import java.util.List;

/**
 * client
 * @author zhongzh
 *
 */
public class MainClass {
    public static void main(String[] args) {
        //String number = "10";
        String number = "20";
        Context context  =  new Context(number);
        
        //Expression expression = new PlusExpression();//递增的表达式/解释器
        /*Expression expression = new MinusExpression();//递减的表达式/解释器
        expression.interpret(context);//对原始的值的数据进行递增.
        
        System.out.println(context.getOutput());//输出结果
        
        
        Expression expression2 = new PlusExpression();
        expression2.interpret(context);
        System.out.println(context.getOutput());//输出结果
        
        Expression expression3 = new PlusExpression();
        expression2.interpret(context);
        System.out.println(context.getOutput());//输出结果
        
        Expression expression4 = new PlusExpression();
        expression2.interpret(context);
        
        
        System.out.println(context.getOutput());//返回自动递增之后的数据
*/    
        
    List<Expression> list = new ArrayList<Expression>();//容器
    list.add(new PlusExpression());
    list.add(new PlusExpression());
    list.add(new MinusExpression());
    list.add(new MinusExpression());
    list.add(new MinusExpression());
    list.add(new MinusExpression());
    list.add(new MinusExpression());
    list.add(new MinusExpression());
    list.add(new MinusExpression());
    
    for (Expression expression : list) {
        expression.interpret(context);
        System.out.println(context.getOutput());
    }
    //System.out.println(context.getOutput());
    }
}
原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6744328.html