[23种设计模式][行为型]06.解释器模式

68 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

1.意图:

给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。

2.适用性:

  • 当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时可使用解释其模式。而当存在一下情况时该模式效果最好:
  • 该文法简单,对于复杂的文法,文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是最好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。
  • 效率不是一个关键问题。

3.解释器(Interpreter)模式构成:

  1. 抽象表达式角色:声明一个所有的具体表达式角色都需要实现的抽象接口。这个接口主要是一个 interpret() 方法,称作解释操作。
  2. 终结符表达式角色:这是一个具体角色
    • 实现了抽象表达式角色所要求的接口,主要是一个 interpret() 方法
    • 文法中的每一个终结符都有一个具体终结表达式与之对应
  3. 非终结符表达式:这是一个具体角色
    • 实现了抽象表达式角色所要求的的接口,主要是一个 interpret() 方法
    • 解释操作以递归方式进行调用
  4. 环境角色:提供解释器之外的一些全局信息
  5. 客户端角色:调用解释操作 interpret()

4.解释器模式UML图:

Image.png

5.解释器模式时序图:

Image.png

6.代码示例:

Image.png

抽象表达式角色:

public abstract class Expression {

    public abstract boolean interpret(Context context);
}

非终结符:

public class Variable extends Expression {

    private String name;

    public Variable(String str) {
        name = str;
    }

    @Override
    public boolean interpret(Context context) {
        return context.lookup(this);
    }
}

环境角色:

public class Constant extends Expression {

    private boolean value;

    public Constant(boolean value) {
        this.value = value;
    }

    @Override
    public boolean interpret(Context context) {
        return value;
    }
}

And:

public class And extends Expression {

    private Expression left;
    private Expression right;

    public And(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public boolean interpret(Context context) {
        return left.interpret(context) && right.interpret(context);
    }
}

Or:

public class Or extends Expression {

    private Expression left;
    private Expression right;

    public Or(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public boolean interpret(Context context) {
        return left.interpret(context) || right.interpret(context);
    }
}

Not:

public class Not extends Expression {

    private Expression exp;

    public Not(Expression exp) {
        this.exp = exp;
    }

    @Override
    public boolean interpret(Context context) {
        return !exp.interpret(context);
    }
}

客户端角色:

public class Client {

    public static void main(String[] args) {
        Context context = new Context();

        Variable x = new Variable("x");
        Variable y = new Variable("y");

        Constant c = new Constant(true);

        context.assign(x, false);
        context.assign(y, true);

        Expression exp = new Or(new And(c, x), new And(y, new Not(x)));

        System.out.println("x = " + x.interpret(context));
        System.out.println("y = " + y.interpret(context));

        System.out.println("exp = {0}" + exp.interpret(context));
    }
}