📢 本文由 gemini-2.5-flash 翻譯
解譯器模式 (Interpreter Pattern) 類行為型模式
意圖
給定一種語言,定義其文法的一種表示法,並定義一個解譯器,此解譯器會使用該表示法來解譯語言中的句子。
結構

其中:
- AbstractExpression 宣告一個程式的解譯操作,此介面為抽象語法樹中所有節點所共享。
- TerminalExpression 實作與文法中終端符號相關聯的解譯操作;一個句子中的每個終端符號需要該類別的一個實例。
- NonterminalExpression 對文法中的每一條規則都需要一個 NonterminalExpression 類別;為每個符號都維護一個 AbstractExpression 類型的實例變數;為文法中的非終端符號實作解譯 (Interpret) 操作。
- Context 包含解譯器之外的一些全域資訊。
- Client 建構 (或被給定) 表示該文法所定義語言中一個特定句子的抽象語法樹,該抽象語法樹由 NonterminalExpression 和 TerminalExpression 的實例組裝而成;呼叫解譯操作。
適用性
解譯器模式適用於當有一種語言需要解譯執行,且可將該語言中的句子表示為一個抽象語法樹時,以下情況效果最佳:
範例
檢查字串:某區域的某人員 (someone of ? region)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| import java.util.*;
public class InterpreterPattern {
public static void main(String[] args) {
Context context = new Context();
context.check("developer of A region");
}
}
class Context{
private String[] regions = {"A region", "B region", "C region"};
private String[] persons = {"developer", "tester"};
private NonterminalExpression nte;
public Context(){
TerminalExpression region = new TerminalExpression(regions);
TerminalExpression person = new TerminalExpression(persons);
nte = new NonterminalExpression(region, person);
}
public void check(String info){
boolean bool = nte.Interpret(info);
if(bool){
System.out.println("正確");
}else {
System.out.println("錯誤");
}
}
}
interface Expression{
public boolean Interpret(String info);
}
class NonterminalExpression implements Expression{
TerminalExpression region;
TerminalExpression person;
public NonterminalExpression(TerminalExpression region, TerminalExpression person){
this.person = person;
this.region = region;
}
@Override
public boolean Interpret(String info){
String[] str = info.split(" of ");
// "developer of A region" --> str = {"developer", "A region"}
return region.Interpret(str[1]) && person.Interpret(str[0]);
}
}
class TerminalExpression implements Expression{
private Set<String> set = new HashSet<>();
public TerminalExpression(String[] data){
for(String str : data){
set.add(str);
}
}
@Override
public boolean Interpret(String info){
return set.contains(info);
}
}
|