友情支持
如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
公众号的微信号是: jikerizhi 。因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。 |
16. 解释器模式
16.1. 定义
根据 GoF 的著名著作 《设计模式》,解释器模式的定义如下:
- 解释器模式(Interpreter)
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来介绍语言中的句子。
《设计模式》
16.2. 类图
解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题[DP]。
因为这个匹配字符的需求在软件的很多地方都会使用,而且行为之间都非常类似,过去的做法是针对特定的需求,编写特定的函数,比如判断Email、匹配电话号码等等,与其为每一个特定需求都写一个算法函数,不如使用一种通用的搜索算法来解释执行一个正则表达式,该正则表达式定义了待匹配字符串的集合[DP]。而所谓的解释器模式,正则表达式就是它的一种应用,解释器为正则表达式定义了一个文法,如何表示一个特定的正则表达式,以及如何解释这个正则表达式。
AbstractExpression(抽象表达式),声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享。
TerminalExpression(终结符表达式),实现与文法中的终结符相关联的解释操作。实现抽象表达式中所要求的接口,主要是一个interpret()方法。文法中每一个终结符都有一个具体终结表达式与之相对应。
NonterminalExpression(非终结符表达式),为文法中的非终结符实现解释操作。对文法中每一条规则R1、R2……Rn都需要一个具体的非终结符表达式类。通过实现抽象表达式的interpret()方法实现解释操作。解释操作以递归方式调用上面所提到的代表R1、R2……Rn中各个符号的实例变量。
Context,包含解释器之外的一些全局信息。
客户端代码,构建表示该文法定义的语言中一个特定的句子的抽象语法树。调用解释操作。
1
2
3
4
5
6
7
8
9
10
11
package com.diguage.didp.interpreter;
/**
* AbstractExpression 类
*
* @author D瓜哥, https://www.diguage.com/
* @since 2017-05-19 17:53:35
*/
public abstract class AbstractExpression {
public abstract void interpret(Context context);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.diguage.didp.interpreter;
import java.util.ArrayList;
import java.util.List;
/**
* Client 类
*
* @author D瓜哥, https://www.diguage.com/
* @since 2017-05-19 17:53:35
*/
public class Client {
public static void main(String[] args) {
Context context = new Context();
List<AbstractExpression> expressions = new ArrayList<>();
expressions.add(new TerminalExpression());
expressions.add(new NonterminalExpression());
expressions.add(new TerminalExpression());
expressions.add(new TerminalExpression());
expressions.forEach(e -> e.interpret(context));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.diguage.didp.interpreter;
/**
* Context 类
*
* @author D瓜哥, https://www.diguage.com/
* @since 2017-05-19 17:53:35
*/
public class Context {
private String input;
private String output;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.diguage.didp.interpreter;
/**
* NonterminalExpression 类
*
* @author D瓜哥, https://www.diguage.com/
* @since 2017-05-19 17:53:35
*/
public class NonterminalExpression extends AbstractExpression {
@Override
public void interpret(Context context) {
System.out.println("非终端解释器!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.diguage.didp.interpreter;
/**
* TerminalExpression 类
*
* @author D瓜哥, https://www.diguage.com/
* @since 2017-05-19 17:53:35
*/
public class TerminalExpression extends AbstractExpression {
@Override
public void interpret(Context context) {
System.out.println("终端解释器!");
}
}