从零开始学设计模式(二十一):解释器模式(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。

目录
相关文章
|
2月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
2月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
2月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
5月前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)
|
6月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
|
6月前
|
设计模式 SQL Java
【设计模式】抖音一面:你不知道解释器模式?
【设计模式】抖音一面:你不知道解释器模式?
51 1
|
6月前
|
设计模式 Go
[设计模式 Go实现] 行为型~解释器模式
[设计模式 Go实现] 行为型~解释器模式
|
6月前
|
设计模式 存储 SQL
【设计模式系列笔记】解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,它定义了一种语言的文法,并且建立一个解释器来解释该语言中的句子。在Java中,解释器模式通常用于实现编程语言解释器、正则表达式解释器等。
59 0
|
15天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    54
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    62
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    57
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    41
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    106
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78