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

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

定义


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


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

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


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


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


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


组成部分


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


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("小明");
    }
}
复制代码


运行结果:

227c25fe226d49eab89710f32e9f28b8~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg

解释器模式的优点


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


解释器模式的缺点


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


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


应用场景


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


总结


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


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


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

目录
相关文章
|
17天前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)
|
2月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
|
2月前
|
设计模式 SQL Java
【设计模式】抖音一面:你不知道解释器模式?
【设计模式】抖音一面:你不知道解释器模式?
26 1
|
2月前
|
设计模式 Go
[设计模式 Go实现] 行为型~解释器模式
[设计模式 Go实现] 行为型~解释器模式
|
2月前
|
设计模式 存储 Java
小谈设计模式(28)—解释器模式
小谈设计模式(28)—解释器模式
|
2月前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
30 1
|
2月前
|
设计模式 存储 Java
23种设计模式,解释器模式的概念优缺点以及JAVA代码举例
【4月更文挑战第7天】解释器模式是一种行为设计模式,它用于定义一个语言的语法表示,并提供一个解释器来处理这种语法。主要用于频繁需要解释执行一组固定语法规则的场景,例如编程语言解释器、规则引擎等。
31 3
|
2月前
|
设计模式 存储 SQL
【设计模式系列笔记】解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法,并且建立一个解释器来解释该语言中的句子。在Java中,解释器模式通常用于实现编程语言解释器、正则表达式解释器等。
21 0
|
2月前
|
设计模式
【设计模式】解释器模式
【设计模式】解释器模式
|
5天前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
41 8