从零开始学设计模式(二十一):解释器模式(Interpreter Pattern)

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

作者的其他平台:

| CSDN:blog.csdn.net/qq\_4115394…

| 掘金:juejin.cn/user/651387…

| 知乎:www.zhihu.com/people/1024…

| GitHub:github.com/JiangXia-10…

| 公众号:1024笔记

本文大概2179字,读完预计需要9分钟

定义

解释器模式(Interpreter Pattern)指的是给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器就是被用来解释这门指定语言中句子。它是一种类行为型模式。

解释器模式类似于计算机的语言的解释器的作用,比如你定义一种语言,然后定义它的一种文法的表示,解释器的作用就是用来解释这门语言的句子,比如定义的语言中#表示我,¥表示你,%表示和,那么#%¥就会被解释器解释成我和你的意思。

这里涉及到了编译原理中的:文法句子语法树的概念。

扫描二维码关注公众号,回复: 13452887 查看本文章

文法:用于描述语言的语法结构的形式规则。比如中文中的主谓宾的语法结构。

句子:就是普通的元素,我们说的话写的文字基本都是句子,它是语言的基本单位,比如这段文字就是一个句子。

语法树:它是句子结构的一种树型表示,它代表了句子的推导结果,它有利于理解句子语法结构的层次。

组成部分

解释器模式主要由以下几个部分组成:

1、抽象表达式(Abstract Expression):声明一个所有具体表达式都要实现的抽象接口(或者抽象类),接口中约定解释器的解释操作,主要包含一个解释方法interpret()方法。具体解释任务由它的各个实现类来完成,具体的解释器分别由终结符解释器TerminalExpression和非终结符解释器NonterminalExpression完成。

2、终结符表达式类(Terminal Expression):是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应

3、非终结符表达式类(Nonterminal Expression):文法中的每条规则对应于一个非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字。非终结符表达式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。

4、环境类(Context):主要包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值

例子

首先定义一个抽象的表达式类:

public abstract class AbstractExpression {
    public abstract boolean  interpreter(String string);
}
复制代码

终结符表达式类:

public class TerminalExpression extends AbstractExpression {
    private Set<String> set = new HashSet<String>();
    public TerminalExpression(String[] strings) {
        for (int i = 0; i < strings.length; i++) {
            set.add(strings[i]);
        }
    }

    @Override
    public boolean interpreter(String string) {
        if(set.contains(string)){
            return true;
        }else{
            return false;
        }
    }
}
复制代码

非终结符表达式:

public class NonterminalExpression extends AbstractExpression  {
    private AbstractExpression person = null;
    private AbstractExpression thing = null;

    public NonterminalExpression(AbstractExpression person, AbstractExpression thing) {
        this.person = person;
        this.thing = thing;
    }

    @Override
    public boolean interpreter(String string) {
        return person.interpreter(string)&&thing.interpreter(string);
    }
}

复制代码

环境类:

public class Context {
    private String[] persons = {"小明","小红","小白"};
    private String behaverior = "吃";
    private String[] things = {"鸡翅","汉堡","牛排"};
    private AbstractExpression exp;
    public Context() {
        //数据初始化
        AbstractExpression personexp = new TerminalExpression(persons);
        AbstractExpression thingexp = new TerminalExpression(things);
        exp = new NonterminalExpression(personexp,thingexp);
    }
    public void operation(String string) {
        //调用相关表达式类的解释方法
        boolean flag = exp.interpreter(string);
        if(!flag){
            System.out.println(string+"吃汉堡");
        }else{
            System.out.println(string+"不吃汉堡");
        }
    }
}
复制代码

测试方法:

public class InterpreterPatternTest {
    public static void main(String[] args) {
        Context context= new Context();
        context.operation("小明");
    }
}
复制代码

运行结果:

解释器模式的优点

解释器是一个简单的语法分析工具,它最显著的优点就是扩展性,修改语法规则只需要修改相应的非终结符就可以了,如果需要扩展语法,你只需要增加非终结符类就可以了,所以拓展性好。

解释器模式的缺点

1、解释器模式的语法规则比较复杂,每个语法都需要指定一个具体的非终结符表达式。所以容易造成代理量过大,而且维护比较复杂。

2、解释器模式需要知道它具体的文法,否则逻辑理解较为复杂。

应用场景

解释器模式在应用中比较少,只有在一些重复发生的计算法则,或者sql语句可以使用解释器进行解释

总结

抽象表达式是生成语法集合的关键,每个非终结符表达式解释一个最小的语法单元,然后通过递归的方式将这些语法单元组合成完整的文法,这就是解释器模式。

解释器模式在实际的使用中比较少,因为它的维护和性能效率是比较复杂的问题,所以对于解释器模式了解即可。

最后本文以及之前的所有的设计模式中的例子代码,都将同步至github,需要的欢迎下载star。

Github地址:

github.com/JiangXia-10…

相关推荐:

从零开始学设计模式(一):什么是设计模式

从零开始学设计模式(二):单例模式

从零开始学设计模式(三):原型模式(Prototype Pattern)

从零开始学设计模式(四):工厂模式(Factory Pattern)

从零开始学设计模式(五):建造者模式(Builder Pattern)

从零开始学设计模式(六):适配器模式(Adapter Pattern)

从零开始学设计模式(六):代理模式(Proxy Pattern)

从零开始学设计模式(八):装饰器模式(Decorator Pattern)

从零开始学设计模式(九):外观模式(Facade Pattern)

从零开始学设计模式(十):桥接模式(Bridge Pattern)

从零开始学设计模式(十一):组合模式(Composite Pattern)

从零开始学设计模式(十二):享元模式(Flyweight Pattern)

从零开始学设计模式(十三):访问者模式(Visitor Pattern)

从零开始学设计模式(十四):中介者模式(Mediator Pattern)

从零开始学设计模式(十五):模版方法模式(Template Method Pattern)

从零开始学设计模式(十六):策略模式(Strategy Pattern)

从零开始学设计模式(十七):备忘录设计模式(Memento Pattern)

从零开始学设计模式(十八):状态模式(State Pattern)

从零开始学设计模式(十九):责任链模式(Chain of Responsibility Pattern)

从零开始学设计模式(二十):迭代器模式(Iterator Pattern)

猜你喜欢

转载自juejin.im/post/7035602538753687588