Java 设计模式——解释器模式(行为型设计模式)

概念介绍

解释器模式是指给定一个使用规定格式和语法的语言,并且建立一个解释器来解释该语言中的句子。解释器本身就是一种按照规定的语法进行解析的方案,但是总体来说也是一种使用频率相对较低但学习难度较大的设计模式。

举例

因为解释器模式用到地方不太多,实在想不到举什么样的例子合适,所以就使用一个简单的来实现一个垒加的功能的例子吧。

具体过程如下:

上下文环境类

@Getter
@Setter
public class Context {
    
    /**
     * 输入
     */
    private String input;
    /**
     * 结果
     */
    private int output;


    public Context(String input){
        this.input = input;
    }

    @Override
    public String toString() {
        return input + "=" + output;
    }
}

抽象表达式类

public abstract class Expression {

    Context context;

    /**
     * 解释一个给定的表达式
     * @param context
     */
    public abstract void interpret(Context context);

}

垒加类

/**
 * 垒加1
 */
public class MinusExpression extends Expression {

    /**
     * 解释一个给定的表达式
     *
     * @param context
     */
    @Override
    public void interpret(Context context) {

        this.context = context;
        String input = context.getInput();
        int in = Integer.valueOf(input);
        context.setOutput(in-1);

    }

    @Override
    public String toString() {
        return "--"+context.getInput()+"="+context.getOutput();
    }
}

垒减

/**
 * 垒减
 */
public class PlusExpression extends Expression {

    /**
     * 解释一个给定的表达式
     *
     * @param context
     */
    @Override
    public void interpret(Context context) {

        this.context = context;
        String input = context.getInput();
        int in = Integer.valueOf(input);
        context.setOutput(in+1);

    }

    @Override
    public String toString() {
        return "++"+context.getInput()+"="+context.getOutput();
    }
}

测试,使用

public class Client {

    public static void main(String[] args) {

        Context context = new Context("50");
        
        Expression plus = new PlusExpression();
        Expression minus = new MinusExpression();
        //执行垒加
        plus.interpret(context);
        System.out.println(plus.toString());
        //垒减
        minus.interpret(context);
        System.out.println(minus.toString());

    }

}

运行结果
++50=51
–50=49
通过运算结果可以看出来,表达式通过解释后的结果,++50解释后结果是51,–50解释后结果是49

解释器模式分析

解释器模式的结构图如下:
在这里插入图片描述
解释器类图上的各个角色说明:

Expression(抽象解释器):定义解释方法,具体的解释任务由各个实现类完成,具体的解释器分别由TerminalRxpression和NonterMinalExpression完成。抽象解释器对应上面例子中的Expression类

TerminalExpression(终结符表达式):实现与文法中的元素相关的解释操作,一个解释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。上面的代码例子中的PlusExpression和MinusExpression都是这个角色。

NoteTerminalExpression(非终结符表达式):文法中的每条规则对应于一个非终结符表达式。非终结符表达式是根据逻辑的复杂度而增加,原则上每个文法规则都对应一个非终结符表达式。由于上面举得例子比较简单,所以上面的例子中是没有这个角色的。

Context(环境角色):环境类又称为上下文类,它用于存储解释器之外的一些全局信息,通常它临时存储了需要解释的语句。也可以使用集合用来存储要解释的内容。

解释器模式总结

解释器模式的优点

1、易于改变和扩展文法。因为该模式使用类表示文法,所以可以使用继承改变或扩展该文法。

2、每条文法规则都可以是一个类,所以可以很方便的实现一个简单的语言。

3、易于实现文法的定义。在抽象语法树中每一个表达式节点类的实现方式都是相似的,这些类的代码编写都不会特别复杂,还可以通过一些工具自动生成节点类代码。

4、增加新的解释表达式较为方便。如果用户需要增加新的解释表达式只需要对应增加一个新的终结符表达式或非终结符表达式类,原有表达式类代码无须修改,符合“开闭原则”。

解释器模式的缺点

1、对于复杂文法难以维护。在解释器模式中,每一条规则至少需要定义一个类,因此如果一个语言包含太多文法规则,类的个数将会急剧增加,导致系统难以管理和维护,此时可以考虑使用语法分析程序等方式来取代解释器模式。

2、执行效率较低。由于在解释器模式中使用了大量的循环和递归调用,因此在解释较为复杂的句子时其速度很慢,而且代码的调试过程也比较麻烦。

适用场景

1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。

2、一些重复出现的问题可以用一种简单的语言来进行表达。
3、一个语言的文法较为简单。

4、执行效率不是关键问题。【注:高效的解释器通常不是通过直接解释抽象语法树来实现的,而是需要将它们转换成其他形式,使用解释器模式的执行效率并不高。】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能吃辣的JAVA程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值