设计模式读书笔记-解释器模式

2016-08-21
读书笔记
  • 定义:给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。不常用。
  • 代码:
public abstract class Expression {
    //解析公式和数值,其中var中的key值是是公式中的参数,value值是具体的数字
    public abstract int interpreter(HashMap<String,Integer> map);

}

public class VarExpression extends Expression{

    private String key;

    public VarExpression(String key){
        this.key = key;
    }

    public int interpreter(HashMap<String, Integer> map) {
        return map.get(key);
    }
}

public abstract class SymbolExpression extends Expression{

    protected Expression left;
    protected Expression right;

    public SymbolExpression(Expression left,Expression right){
        this.left = left;
        this.right = right;
    }
}

public class AddExpression extends SymbolExpression{

    public AddExpression(Expression left, Expression right) {
        super(left, right);
    }

    public int interpreter(HashMap<String, Integer> map) {
        return super.left.interpreter(map) + super.right.interpreter(map);
    }
}

public class SubExpression extends SymbolExpression{

    public SubExpression(Expression left, Expression right) {
        super(left, right);
    }

    public int interpreter(HashMap<String, Integer> map) {
        return super.left.interpreter(map) - super.right.interpreter(map);
    }

}

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 SubExpression(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.interpreter(var);
    }
}

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))){ //解决重复参数的问题
                    System.out.print("请输入"+ch+"的值:");
                    String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
                    map.put(String.valueOf(ch),Integer.valueOf(in));
                }
            }
        }
        return map;
    }
}

Kommentare: