Home 解释器模式
Post
Cancel

解释器模式

Interpreter Pattern 类行为型模式

意图

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子

结构

解释器模式

其中:

  • AbstractExpression 声明一个程序的解释操作,这个接口为抽象语法树中所有的结点所共享
  • TerminalExpression 实现与文法中的终结符相关联的解释操作;一个句子中的每个终结符需要该类的一个实例
  • NonterminalExpression 对文法中的每一条规则都需要一个 NonterminalExpression 类;为每个符号都维护一个 AbstractExpression 类型的实例变量;为文法中的非终结符实现解释 (Interpret) 操作
  • Context 包含解释器之外的一些全局信息
  • Client 构建 (或被给定) 表示该文法定义的语言中一个特定的句子的抽象语法树,该抽象语法树由 NonterminalExpression 和 TerminalExpression 的实例装配而成;调用解释操作

适用性

Interpreter 模式适用于当有一个语言需要解释执行,并且可将该语言中的句子表示为一个抽象语法树时,以下情况效果最好:

  • 该文法简单
  • 效率不是一个关键问题

例子

检查字符串:某区的某人员 (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("right");
        }else {
            System.out.println("wrong");
        }
    }
}

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);
    }
}
This post is licensed under CC BY 4.0 by the author.

命令模式

迭代器模式