一天一个设计模式---解释器模式

来源:互联网 发布:a5淘宝客论坛 编辑:程序博客网 时间:2024/05/16 07:30

介绍:给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的例子。

一、角色及作用

可能上面对解释器模式的解释十分难以理解,为什么我们写代码又和语言有关了。这里我举个例子

你是大神你是高富帅

这里可以解释成 - 你是[名词]的形式

我是菜鸟我是穷矮丑

结合上面,我们可以解释成 - [名词]是[名词]的形式

角色 作用 抽象表达式 抽象的解释操作父类,并定义一个抽象的解释方法 终结符表达式 实现文法中与元素相关联的解释操作,比如 A + B 这里A,B是终结符 非终结符表达式 实现文法中与非终结符有关的解释操作,非终结符表达式一般是文法中的运算符或者其他关键字 环境类 包含解释器之外的全局信息

二、打造加法计算器

抽象表达式

public abstract class ArithmeticExpression {    public abstract int interpret();}

数字解释器,终结符表达式

public class NumExpression extends ArithmeticExpression {    private int num;    public NumExpression(int num) {        this.num = num;    }    @Override    public int interpret() {        return num;    }}

运算符抽象解释器,因为有多种运算符,方便以后维护

public abstract class OperatorExpression extends ArithmeticExpression {    protected ArithmeticExpression exp1, exp2;    public OperatorExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {        this.exp1 = exp1;        this.exp2 = exp2;    }}

加法解释器,非终结符表达式

public class AdditionExpression extends OperatorExpression {    public AdditionExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {        super(exp1, exp2);    }    @Override    public int interpret() {        return exp1.interpret() + exp2.interpret();    }}

计算器,环境类

public class Calculator {    // 使用stack,后进先出,记录所有操作    private Stack<ArithmeticExpression> stack = new Stack<ArithmeticExpression>();    // 这里规定好,数字和符号之间用空格分隔    public int calculate(String exp) {        String[] eles = exp.split(" ");        for (int i = 0; i < eles.length; i++) {            NumExpression front = null; // 保留运算符前面的值            NumExpression next = null;// 保留运算符后面的值            switch (eles[i]) {            case "+":                front = (NumExpression) stack.peek();                next = new NumExpression(Integer.valueOf(eles[++i]));                stack.push(next);                stack.push(new AdditionExpression(front, next));                break;            default:                // 其他为数字                stack.push(new NumExpression(Integer.valueOf(eles[i])));                break;            }        }        return stack.peek().interpret();    }}

三、我们还需要减法

增加减法,十分方便!

减法解释器

public class SubtractExpression extends OperatorExpression {    public SubtractExpression(ArithmeticExpression exp1, ArithmeticExpression exp2) {        super(exp1, exp2);    }    @Override    public int interpret() {        return exp1.interpret() - exp2.interpret();    }}

计算器

......case "-":    front = (NumExpression) stack.peek();    next = new NumExpression(Integer.valueOf(eles[++i]));    stack.push(next);    stack.push(new SubtractExpression(front, next));    break;......

四、看看结果

Calculator c = new Calculator();System.out.println(c.calculate("1 + 4"));System.out.println(c.calculate("1 - 4"));

输出

5-3

总结:解释器模式能灵活地实现扩展,实现时只需要增加非终结符来实现相关业务。缺点也是类的数量的膨胀,对于负责的文法,解释器的结构树也会十分负责,难以维护


更多模式:一天一个设计模式—分类与六大原则

更多源码: https://github.com/oDevilo/Java-Base

0 0
原创粉丝点击