IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 设计模式之解释器模式 -> 正文阅读

[Java知识库]设计模式之解释器模式

1. 解释器模式概念

计算机用来解释句子或表达式,类似在软件开发过程中,有时需要处理一系列多次重复出现的问题。如果将这类问题归纳成一种简单的语言,那么这些问题实例将是该语言的一些句子,这样就可以用编译原理中的解释器模式来实现了。

解释器模式的定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解释器来解释语言中的句子,即用编译语言的方式来分析应用中的实例。

解释器模式优点:

  • 扩展性好,由于在解释器模式中使用类来表示语言的文法规则,因此可以通过继承等机制来改变或扩展文法。
  • 容易实现,在语法树中的每个表达式节点类都是相似的,所以实现其文法较为容易。

解释器模式缺点:

  • 执行效率较低,解释器模式中通常使用大量的循环和递归调用,当要解释的句子比较复杂时,其运行速度很慢,且代码的调试过程也比较麻烦。
  • 会引起类膨胀,解释器模式中的每条规则至少需要定义一个类,当包含的文法规则很多时,类的个数将急剧增加,导致系统难以管理与维护。
  • 可应用的场景比较少,在软件开发中,需要定义语言文法的应用实例非常少,所以这种模式很少被使用到。

解释器模式类图如下:

在这里插入图片描述

  • 环境(Context):用于封装解释器的全局信息,主要任务是将需要分析的句子或表达式转化成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法。
  • 抽象表达式(AbstractExpression):定义解释器的接口,约定解释器的解释操作。
  • 终结符表达式(TerminalExpression):抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之对应。
  • 非终结符表达式(NonterminalExpression):抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应一个非终结符表达式。

2. 解释器模式案例

使用解释器的方式实现加减运算,例如输入表达式a+b+c-d,a=10,b=50,c=20,d=10,输出计算结果。

2.1 抽象表达式

新建抽象表达式接口,约定解释器的解释操作,接口名称为Expression,内容如下:

public interface Expression {

    /**
     * 获取解释结果
     * @param map 表达式键值对
     * @return 返回解释后的值
     */
    Integer interpret(Map<String, Integer> map);
}

2.2 终结符表达式

在加减运算中,变量不可以继续进行推演运算属于终结符,新建变量表达式类,解释操作返回自身的值,类名为VariableExpression,内容如下:

public class VariableExpression implements Expression {

    private String variableKey;

    public VariableExpression(String variableKey){
        this.variableKey = variableKey;
    }

    @Override
    public Integer interpret(Map<String, Integer> map) {
        return map.get(variableKey);
    }
}

2.3 非终结符表达式

在加减运算中,运算符号“+”与“-”可以继续推导属于非终结符,新建非终结符表达式基类,定义左右两个表达式属性,类名为SymbolExpression,内容如下:

public class SymbolExpression implements Expression{

    protected Expression leftExpression;

    protected Expression rightExpression;

    public SymbolExpression(Expression leftExpression, Expression rightExpression){
        this.leftExpression = leftExpression;
        this.rightExpression = rightExpression;
    }

    @Override
    public Integer interpret(Map<String, Integer> map) {
        return 0;
    }
}

新建加法非终结符表达式类用来解释加法,类名为AddSymbolExpression,内容如下:

public class AddSymbolExpression extends SymbolExpression{

    public AddSymbolExpression(Expression leftExpression, Expression rightExpression) {
        super(leftExpression, rightExpression);
    }

    @Override
    public Integer interpret(Map<String, Integer> map) {
        return leftExpression.interpret(map) + rightExpression.interpret(map);
    }
}

类似新建减法终结符表达式类用来解释减法,类名为SubSymbolExpression,内容如下:

public class SubSymbolExpression extends SymbolExpression {

    public SubSymbolExpression(Expression leftExpression, Expression rightExpression) {
        super(leftExpression, rightExpression);
    }

    @Override
    public Integer interpret(Map<String, Integer> map) {
        return leftExpression.interpret(map) - rightExpression.interpret(map);
    }
}

2.4 环境

新建环境类用来执行解析表达式,类名为Calculator,内容如下:

public class Calculator {

    /**
     * 最终表达式
     */
    private Expression expression;

    public Calculator(String expression) {
        char[] charArray = expression.toCharArray();
        Stack<Expression> stack = new Stack();
        Expression left;
        Expression right;
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]){
                case '+':
                    // 加法运算符表达式构建
                    left = stack.pop();
                    right = new VariableExpression(String.valueOf(charArray[++i]));
                    stack.push(new AddSymbolExpression(left, right));
                    break;
                case '-':
                    // 减法运算符表达式构建
                    left = stack.pop();
                    right = new VariableExpression(String.valueOf(charArray[++i]));
                    stack.push(new SubSymbolExpression(left, right));
                    break;
                default:
                    // 操作数进栈
                    stack.push(new VariableExpression(String.valueOf(charArray[i])));
                    break;
            }
        }
        this.expression = stack.pop();
    }

    /**
     * 获取表达式结果
     * @param map 变量表
     * @return 运算结果
     */
    public Integer calculate(Map<String, Integer> map){
        return expression.interpret(map);
    }
}

2.5 客户端

新建客户端测试,内容如下:

public class Client {
    public static void main(String[] args) {
        // 准备表达式
        String expression = "a+b+c-d";

        // 准备变量表
        Map<String, Integer> map = new HashMap(){{
            put("a", 10);
            put("b", 50);
            put("c", 20);
            put("d", 10);
        }};

        // 创建解释器上下文
        Calculator calculator = new Calculator(expression);

        // 获取表达式的结果
        Integer result = calculator.calculate(map);
        // 打印表达式结果
        System.out.println("result = " + result);
    }
}

在这里插入图片描述

3. 解释器模式应用

解释器模式适用于表达式被解释并转换为其内部表示的情况。在JAVA的Pattern中实现了解释器模式,它用于解析正则表达式。在解释正则表达式时返回匹配器对象,匹配器使用基于正则表达式的模式类创建的内部结构,使用如下:

public class Test {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("a*b");
        Matcher matcher = pattern.matcher("aaaaaaab");
        boolean result = matcher.matches();
        System.out.println("result = " + result);
    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 21:59:56  更:2022-03-11 22:02:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:27:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码