天天看点

行为型模式-11解释器模式

文章目录

    • 十一、解释器模式
      • 1. `定义`
      • 2. `结构`
      • 3. `案例`
      • 4. `代码`
      • 5. `优缺点`
      • 6. `使用场景`

十一、解释器模式

1.

定义

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

2.

结构

  • 抽象表达式角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。
  • 终结符表达式角色:是抽象表达式的子类,用来实现文法中与终结 符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。
  • 非终结符表达式角色:也是抽象表达式的子类,用来实现文法 中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。
  • 环境角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有 解释器共享的数据,后面的解释器可以从这里获取这些值。
  • 客户端:主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语 法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。

3.

案例

  • 加减文本运算
  • UML
行为型模式-11解释器模式

4.

代码

  • AbsExpression
/**
 * 抽象表达式类
 */
public abstract class AbsExpression {
    public abstract int interpret(Context context);
}
           
  • Context
/**
 *  环境角色类
 */
public class Context {
    //定义map集合,存储变量和对应的值
    private Map<Variable,Integer> map = new HashMap<>();
    //添加变量的方法
    public void addVar(Variable var,Integer value){
        map.put(var,value);
    }
    public int getValue(Variable var){
        return map.get(var);
    }
}
           
  • Variable
/**
 * 封装变量的类
 */
public class Variable extends AbsExpression{
    //声明存储变量名的成员变量
    private String name;
    public Variable(String name){
        this.name = name;
    }
    public int interpret(Context context){
        //返回变量的值
        return context.getValue(this);
    }

    @Override
    public String toString() {
        return name;
    }
}
           
  • Minus
/**
 * 减法表达式类
 */
public class Minus extends AbsExpression{
    //减号左边的表达式
    private AbsExpression left;
    //减号右边的表达式
    private AbsExpression right;

    public Minus(AbsExpression left, AbsExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Context context) {
        return left.interpret(context) - right.interpret(context);
    }

    @Override
    public String toString() {
        return "(" + left.toString() + " - " + right.toString() + ")";
    }
}
           
  • Plus
/**
 * 加法表达式类
 */
public class Plus extends AbsExpression {

    //+号左边的表达式
    private AbsExpression left;
    //+号右边的表达式
    private AbsExpression right;

    public Plus(AbsExpression left, AbsExpression right) {
        this.left = left;
        this.right = right;
    }

    public int interpret(Context context) {
        //将左边表达式的结果和右边表达式的结果进行相加
        return left.interpret(context) + right.interpret(context);
    }

    @Override
    public String toString() {
        return "(" + left.toString() + " + " + right.toString() + ")";
    }
}
           
  • 测试类
public class Client {
    public static void main(String[] args) {
        //创建环境对象
        Context context = new Context();

        //创建多个变量对象
        Variable v1 = new Variable("a");
        Variable v2 = new Variable("b");
        Variable v3 = new Variable("c");
        Variable v4 = new Variable("d");

        //将变量存储到环境对象中
        context.addVar(v1,2);
        context.addVar(v2,3);
        context.addVar(v3,4);
        context.addVar(v4,5);
        AbsExpression expression = new Minus(v1,new Minus(new Minus(v2,v3),v4));
        //解释:计算
        int rs = expression.interpret(context);
        System.out.println(expression+"="+rs);
        System.out.println("(2 - ((3 - 4) - 5))=8");
    }
}
//测试结果
//(a - ((b - c) - d))=8
//(2 - ((3 - 4) - 5))=8
           

5.

优缺点

  • 优点

    • 易于改变和扩展方法
    • 实现文法较为容易
    • 增加新饿解释表达式较为方便
  • 缺点

    • 执行效率低

6.

使用场景

  • 当问题重复出现,且可以用一种简单的语言来进行表达时
  • 当语言的文法较为简单,执行效率不是关键问题时