CHARLIE SAYS

查理如是说
DATE 2026-08-24
THEME
SERIES / DESIGN_PATTERNS / P-112 · 设计模式

设计模式 018:解释器(Interpreter)

解释器模式(Interpreter pattern)为语言创建解释器,通常由语言的语法和语法分析来定义。给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

意图

为语言创建解释器,通常由语言的语法和语法分析来定义。

类图

  • TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression
  • Context:上下文,包含解释器之外的一些全局信息,本例中就是 String

原文图片丢失,据文字重绘。

classDiagram
    class Expression {
        <<abstract>>
        +interpret(String) boolean
    }
    class TerminalExpression {
        -String literal
        +interpret(String) boolean
    }
    class AndExpression {
        -Expression expression1
        -Expression expression2
        +interpret(String) boolean
    }
    class OrExpression {
        -Expression expression1
        -Expression expression2
        +interpret(String) boolean
    }
    Expression <|-- TerminalExpression
    Expression <|-- AndExpression
    Expression <|-- OrExpression
    AndExpression o-- Expression
    OrExpression o-- Expression

实现

以下是一个规则检验器实现,具有 and 和 or 规则,通过规则可以构建一颗解析树,用来检验一个文本是否满足解析树定义的规则。例如一颗解析树为 D And (A Or (B C)),文本 “D A” 满足该解析树定义的规则。这里的 Context 指的是 String。

抽象表达式:

public abstract class Expression {
    public abstract boolean interpret(String str);
}

终结符表达式,判断文本中是否出现某个字面值:

public class TerminalExpression extends Expression {

    private String literal = null;

    public TerminalExpression(String str) {
        literal = str;
    }

    public boolean interpret(String str) {
        StringTokenizer st = new StringTokenizer(str);
        while (st.hasMoreTokens()) {
            String test = st.nextToken();
            if (test.equals(literal)) {
                return true;
            }
        }
        return false;
    }
}

非终结符表达式,组合两棵子解析树:

public class AndExpression extends Expression {

    private Expression expression1 = null;
    private Expression expression2 = null;

    public AndExpression(Expression expression1, Expression expression2) {
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    public boolean interpret(String str) {
        return expression1.interpret(str) && expression2.interpret(str);
    }
}

public class OrExpression extends Expression {

    private Expression expression1 = null;
    private Expression expression2 = null;

    public OrExpression(Expression expression1, Expression expression2) {
        this.expression1 = expression1;
        this.expression2 = expression2;
    }

    public boolean interpret(String str) {
        return expression1.interpret(str) || expression2.interpret(str);
    }
}

客户端构建解析树并解释文本:

public class Client {

    /**
     * 构建解析树
     */
    public static Expression buildInterpreterTree() {
        // Literal
        Expression terminal1 = new TerminalExpression("A");
        Expression terminal2 = new TerminalExpression("B");
        Expression terminal3 = new TerminalExpression("C");
        Expression terminal4 = new TerminalExpression("D");
        // B C
        Expression alternation1 = new OrExpression(terminal2, terminal3);
        // A Or (B C)
        Expression alternation2 = new OrExpression(terminal1, alternation1);
        // D And (A Or (B C))
        return new AndExpression(terminal4, alternation2);
    }

    public static void main(String[] args) {
        Expression define = buildInterpreterTree();
        String context1 = "D A";
        String context2 = "A B";
        System.out.println(define.interpret(context1));
        System.out.println(define.interpret(context2));
    }
}

输出:

true
false

“D A” 同时包含 D 和(A 或 B 或 C 之一),满足 D And (A Or (B C)),输出 true;“A B” 缺少 D,输出 false。

JDK 中的应用

  • java.util.Pattern
  • java.text.Normalizer
  • All subclasses of java.text.Format
  • javax.el.ELResolver

系列导航

← Angular 22+ 教程 18:依赖注入——注入器层级与注入上下文 目录 软件工程 018:阿里巴巴 Java 开发手册 →
← 返回文章列表