概述
作者平台:
| 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)指的是给定一种语言,定义它的文法的一种表示,并定义一个解释器,这个解释器就是被用来解释这门指定语言中句子。它是一种类行为型模式。
解释器模式类似于计算机的语言的解释器的作用,比如你定义一种语言,然后定义它的一种文法的表示,解释器的作用就是用来解释这门语言的句子,比如定义的语言中#表示我,¥表示你,%表示和,那么#%¥就会被解释器解释成我和你的意思。
这里涉及到了编译原理中的:文法、句子和语法树的概念。
文法:用于描述语言的语法结构的形式规则。比如中文中的主谓宾的语法结构。
句子:就是普通的元素,我们说的话写的文字基本都是句子,它是语言的基本单位,比如这段文字就是一个句子。
语法树:它是句子结构的一种树型表示,它代表了句子的推导结果,它有利于理解句子语法结构的层次。
组成部分
解释器模式主要由以下几个部分组成:
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)
最后
以上就是直率鸭子为你收集整理的从零开始学设计模式(二十一):解释器模式(Interpreter Pattern)定义组成部分例子解释器模式的优点解释器模式的缺点应用场景总结的全部内容,希望文章能够帮你解决从零开始学设计模式(二十一):解释器模式(Interpreter Pattern)定义组成部分例子解释器模式的优点解释器模式的缺点应用场景总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复