设计模式---解释器模式

定义

解释器模式:给定一门语言,定义 它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

 

解释器模式通常有一下几种角色:

● AbstractExpression——抽象解释器

具体的解释任务由各个实现类完成,具体的解释器分别由TerminalExpression和NonterminalExpression完成。 也就是下面例子的VarExpression和SymbolExpression。

● TerminalExpression——终结符表达式

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

● NonterminalExpression——非终结符表达式

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

● Context——环境角色

具体到我们的例子中是采用HashMap代替。

 

案例

/**
 * 抽象表达式类
 */
public abstract class Expression {

    /**
     * 解析公式和数值,其中var中的key值是公式中的参数,value值是具体的数字
     * @param var
     * @return
     */
    public abstract int interpreter(Map<String, Integer> var);

}

 

/**
 * 变量解析器
 */
public class VarExpression extends Expression {

    //表达式的参数
    private String key;

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

    @Override
    public int interpreter(Map<String, Integer> var) {
        //获取表达式参数对应的数值
        return var.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);
    }

    @Override
    public int interpreter(Map<String, Integer> var) {
        //相加
        return super.left.interpreter(var) + super.right.interpreter(var);
    }
}

 

/**
 * 减法解析器
 */
public class SubExpression extends SymbolExpression {

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

    @Override
    public int interpreter(Map<String, Integer> var) {
        //相减
        return super.left.interpreter(var) - super.right.interpreter(var);
    }
}

 

/**
 * 解释器封装类
 */
public class Calculator {

    private Expression expression;

    public Calculator(String expStr) {

        //定义一个栈,安排运算的先后顺序
        Stack<Expression> stack = new Stack<>();
        //表达式拆分为字符数组
        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(Map<String, Integer> var) {
        return this.expression.interpreter(var);
    }

}

 

public class InterpreterPatternDemo {

    public static void main(String[] args) throws IOException {
        String expStr = getExpStr();
        Map<String, Integer> var = getValue(expStr);
        Calculator cal = new Calculator(expStr);
        System.out.print("运算结果为:"+expStr +"="+cal.run(var));
    }

    //获得表达式
    public static String getExpStr() throws IOException {
        System.out.print("请输入表达式:");
        return new BufferedReader(new InputStreamReader(System.in)).readLine();
    }

    //获得值映射
    public static Map<String, Integer> getValue(String expStr) throws IOException {
        Map<String, Integer> map = new HashMap<>();
        for (char ch : expStr.toCharArray()) {
            if (ch != '+' && ch != '-') {
                System.out.print("请输入" + ch + "的值:");
                String in = new BufferedReader(new InputStreamReader(System.in)).readLine();
                map.put(String.valueOf(ch), Integer.valueOf(in));
            }
        }
        return map;
    }
    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值