大话设计模式二十二:解释器模式

一.模式定义

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

Interpreter Pattern:Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.

 

二.模式要素

AbstractExpression 抽象表达式:抽象表达式,声明一个抽象的解释操作弗雷,并定义一个抽象的解释方案,其具体的实现在各个具体的子类解释器中完成

TerminalExpression 终结符表达式:终结符表达式,实现文法中终结符有关的解释操作。文法中每一个终结符都有一个具体的终结表达式与之对应

NoterminalExpression 非终结符表达式:非终结表达式,实现文法中非终结符有关的解释操作

Context 环境角色:上下文环境,包含解释器之外的全局信息

 

三.举例说明

我们通过对算术表达式的解释来看一个解释器模式的实现, 如表达式m+n+p中,如果我们使用解释器模式对该表达式进行解释,那么mnp代表的三个字母可以看成是终结符号,而+代表的运算符则可以看成是非终结符号。

 

四.具体代码

AbsExpression.java 抽象表达式

package interpreterpattern;

/**
 * author: lllddd
 * created on: 2021/3/15 21:55
 * description:抽象表达式类
 */
public abstract class AbsExpression {
    /**
     * 解释执行
     *
     * @return 解释执行的返回值
     */
    public abstract int interpret();
}

VarExpression.java 数值表达式

package interpreterpattern;

/**
 * author: lllddd
 * created on: 2021/3/15 21:57
 * description:值表达式
 */
public class VarExpression extends AbsExpression {
    private final int num;

    public VarExpression(int num) {
        this.num = num;
    }

    @Override
    public int interpret() {
        return num;
    }
}

AddExpression.java 加法表达式

package interpreterpattern;

/**
 * author: lllddd
 * created on: 2021/3/15 21:58
 * description:加法表达式
 */
public class AddExpression extends AbsExpression {
    private AbsExpression left;
    private AbsExpression right;

    public AddExpression(AbsExpression left, AbsExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() + right.interpret();
    }
}

SubExpression.java 减法表达式

package interpreterpattern;

/**
 * author: lllddd
 * created on: 2021/3/15 21:59
 * description:减法表达式
 */
public class SubExpression extends AbsExpression {
    private AbsExpression left;
    private AbsExpression right;

    public SubExpression(AbsExpression left, AbsExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret() {
        return left.interpret() - right.interpret();
    }
}

Calculator.java 计算器

package interpreterpattern;

import java.util.Stack;

/**
 * author: lllddd
 * created on: 2021/3/15 22:03
 * description:运算器
 */
public class Calculator {
    private AbsExpression expression;

    public Calculator(String inputStr) {
        Stack<AbsExpression> expressionStack = new Stack<>();

        AbsExpression leftExpression = null;
        VarExpression rightExpression = null;

        // 根据空格来提取元素
        String[] inputArray = inputStr.split(" ");

        for (int i = 0; i < inputArray.length; i++) {
            if (inputArray[i].equals("+")) {
                leftExpression = expressionStack.pop();
                rightExpression = new VarExpression(Integer.parseInt(inputArray[++i]));
                expressionStack.push(new AddExpression(leftExpression, rightExpression));
            } else if (inputArray[i].equals("-")) {
                leftExpression = expressionStack.pop();
                rightExpression = new VarExpression(Integer.parseInt(inputArray[++i]));
                expressionStack.push(new SubExpression(leftExpression, rightExpression));
            } else {
                expressionStack.push(new VarExpression(Integer.parseInt(inputArray[i])));
            }
        }
        this.expression = expressionStack.pop();
    }

    /**
     * 执行计算
     *
     * @return 返回计算结果
     */
    public int calculate() {
        return expression.interpret();
    }
}

Main.java 调用类

package interpreterpattern;

/**
 * author: lllddd
 * created on: 2021/3/15 21:01
 * description:调用类
 */
public class Main {
    public static void main(String[] args) {
        Calculator calculator = new Calculator("3 + 10 - 8 + 11 - 1");
        System.out.println(calculator.calculate());
    }
}

运行结果:

 

五.总结

1.解释器模式的优点

解释器是一个简单语法分析工具,它最显著的特点就是扩展性,修改语法规则只需要修改相应的非终结符表达式即可,若要扩展语法,只要增加非终结符类即可。

2.解释器模式的缺点

(1)解释器模式会引起类膨胀

(2)解释器模式采用递归调用方法

(3)效率问题

3.解释器模式的适用场景

(1)重复发生的问题可以使用解释器模式

(2)一个简单语法需要解释的场景

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值