设计模式--解释器模式【行为型模式】

设计模式的分类

我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:

  • 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型模式(7 种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式(11 种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

在这里插入图片描述

设计模式系列文章传送门

设计模式的 7 大原则

设计模式–单例模式【创建型模式】

设计模式–工厂方法模式【创建型模式】

设计模式–抽象工厂模式【创建型模式】

设计模式–建造者模式【创建型模式】

设计模式–原型模式【创建型模式】

设计模式–适配器模式【结构型模式】

设计模式–装饰器模式【结构型模式】

设计模式–代理模式【结构型模式】

设计模式–外观模式(门面模式)【结构型模式】

设计模式–桥接模式【结构型模式】

设计模式–组合模式【结构型模式】

设计模式–享元模式【结构型模式】

设计模式–策略模式【行为型模式】

设计模式–模板方法模式【行为型模式】

设计模式–观察者模式【行为型模式】

设计模式–迭代器模式【行为型模式】

设计模式–责任链模式【行为型模式】

设计模式–命令模式【行为型模式】

设计模式–备忘录模式【行为型模式】

设计模式–状态模式【行为型模式】

设计模式–访问者模式【行为型模式】

设计模式–中介者模式【行为型模式】

什么是解释器模式

解释器模式(Interpreter Pattern)是一种行为设计模式,解释器模式通过一个解释器对象处理一个语法规则,把复杂的功能分离开,然后选择需要被执行的功能,并把这些功能组合成为需要被解释执行的抽象语法树,再按照抽象语法树来解释执行,实现相应的功能。

解释器模式的组成部分

  • 抽象表达式:也可以叫抽象解释器,声明一个抽象的解释操作方法,这个方法是一个抽象方法,由具体子类实现。
  • 终止表达式:也可以叫终止符解释器,实现了抽象解释器,实现与语法规则中的终结符相关联的解释操作,在语法规则的语法分析树中,终结符表达式是叶子节点,它们不再包含其他表达式,这也是终止的意思的来源。
  • 非终止表达式:也可以叫非终止符解释器,实现了抽象解释器,对语法规则中的非终结符进行解释操作,非终结符解释器通常包含其他表达式(终结符表达式或非终结符表达式),它在在语法规则的语法分析树中是非叶子节点。
  • 上下文:包含解释器之外的一些全局信息,它为解释器的解释工作提供必要的支持。

解释器模式案例演示

解释器模式相对来说是比较冷门的设计模式,这里我准备使用生活中的加减法来演示解释器模式,例如:x + y 或者 x + y - z,下面我们使用代码来进行演示。

AbstractExpression(抽象表达式)

AbstractExpression 抽象表达式,定义了解释方法,具体代码如下:

public interface AbstractExpression {

    ///解释方法
    int interpretation();

}

ConstantExpression(终止表达式)

ConstantExpression 是一个终止表达式,同时也是一个常量表达式,实现了抽象表达式接口,并实现了解释方法,具体代码如下:

public class ConstantExpression implements AbstractExpression {

    private int number;

    public ConstantExpression(int number) {
        this.number = number;
    }

    @Override
    public int interpretation() {
        return number;
    }

}

NumExpression(终止表达式)

NumExpression 也是一个终止表达式,但它可以从上下文中获取值,同样也实现了抽象表达式接口,并实现了解释方法,具体代码如下:

public class NumExpression implements AbstractExpression{

    private String name;

    public NumExpression(String name) {
        this.name = name;
    }

    @Override
    public int interpretation() {
        return InterpretationContext.getValue(this.name);
    }
}

AddExpression(非终止表达式)

AddExpression 是一个非终止表达式,它持有两个抽象表达式对象,同样也实现了抽象表达式接口,实现了解释方法,并在解释方法中实现了加法计算,具体代码如下:

public class AddExpression implements AbstractExpression {

    private AbstractExpression left;

    private AbstractExpression right;

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

    //实现加法
    @Override
    public int interpretation() {
        return left.interpretation() + right.interpretation();
    }
}

SubExpression(非终止表达式)

SubExpression 是一个非终止表达式,它持有两个抽象表达式对象,同样也实现了抽象表达式接口,实现了解释方法,并在解释方法中实现了减法计算,具体代码如下:

public class SubExpression implements AbstractExpression {

    private AbstractExpression left;

    private AbstractExpression right;

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

    //实现减法
    @Override
    public int interpretation() {
        return left.interpretation() - right.interpretation();
    }
}

InterpretationContext(上下文)

InterpretationContext 上下文中有一个 Map 容器,负责存储变量名和值之间的映射关系,并提供了存取值的方法,具体代码如下:

public class InterpretationContext {

    private static final Map<String, Integer> INTERPRETATION_MAP = new HashMap<>();

    public static int getValue(String key) {
        return INTERPRETATION_MAP.get(key) == null ? 0 : INTERPRETATION_MAP.get(key);
    }

    public static void putValue(String key, Integer value) {
        INTERPRETATION_MAP.put(key, value);
    }

}

InterpretationClient(客户端)

InterpretationClient 客户端代码如下:

public class InterpretationClient {

    public static void main(String[] args) {
        NumExpression x = new NumExpression("x");
        NumExpression y = new NumExpression("y");
        InterpretationContext.putValue("x", 88);
        InterpretationContext.putValue("y", 66);
        //执行表达式:x+y
        AddExpression addExpression = new AddExpression(x, y);
        int addInterpretation = addExpression.interpretation();
        System.out.println("执行表达式:x+y 的结果:" + addInterpretation);
        //执行表达式:x+y-54
        ConstantExpression constantExpression = new ConstantExpression(54);
        SubExpression subExpression = new SubExpression(addExpression, constantExpression);
        int subInterpretation = subExpression.interpretation();
        System.out.println("执行表达式:x+y-54 的结果:" + subInterpretation);

    }

}

执行结果如下:

执行表达式:x+y 的结果:154
执行表达式:x+y-54 的结果:100

可以看到我们使用解释器模式完成了 x + y 和 x + y - 100 的运算,结果符合预期。

解释器模式的优缺点

优点:

  • 容易实现语法规则,解释器模式通过将语法规则表示为类层次结构,使得实现特定的语法规则变得相对容易,例如:x + y - 100。
  • 扩展性好,解释器模式允许对语言的语法进行修改和扩展,由于语法规则是通过类来表示的,所以可以在运行时动态地改变语言的解释方式,来满足不同的需求。
  • 代码维护下良好,因为每个语法规则都被封装在独立的类中,所以当需要修改某个语法规则的解释逻辑时,只需要在对应的类中进行修改,而不会影响到其他语法规则的解释。

缺点:

  • 当语法规则变得复杂时,解释器模式的实现会变得非常复杂。
  • 解释器模式需要定义很多类和解释方法,因此代码量比较大,实现起来比较复杂。
  • 解释器模式通常采用递归的方式来解释语法规则,在处理复杂的语法或者大量的数据时,递归调用可能会导致性能下降。

解释器模式的使用场景

  • 数学表达式的场景。
  • 有业务规则的场景可以考虑使用解释器模式。

总结:本篇分享了解释器模式的概念和使用,并使用加减法的案例进行了代码演示,希望可以帮助到有需要了解解释器模式的朋友们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值