6解释器模式

解释器模式

解释器模式(Interpreter Pattern)是一种按照规定语法对表达式进行解析的方案,在项目中使用较少。

1解释器模式的定义
解释器模式的英文原话:
    Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
意思是:给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。

解释器有5个角色:
  • 抽象表达式(Abstract Expression)角色:该角色声明一个所有的具体表达式角色都需要实现的抽象接口,该接口主要是一个解释操作interpret()方法。
  • 终结符表达式(Terminal Expression)角色:该角色实现了抽象表达式角色所要求的接口,文法中的每一个终结符都有一个具体终结表达式与之对应。
  • 非终结符表达式(Noneterminal Expression)角色:该角色是一个具体角色,文法中的每一条规则都对应一个非终结符表达式类。
  • 环境(Context)角色:该角色提供解释器之外的一些全局信息。
  • 客户端(Client)角色:   该角色创建一个抽象语法树,调用解释操作。

2解释器模式的应用
a.解释器模式的优缺点
    解释模式的优点
    •    简单的语法分析工具
    • 扩展性,修改语法规则只要修改相应的非终结符表达式即可,若扩展语法,则只要增加非终结符类即可。
    解释器模式的缺点
    • 解释器模式会引起类膨胀。每个语法都要产生一个非终结符表达式,语法比较复杂时就可能产生大量的类文件,不易维护。
    • 采用递归调用方法。每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的结果,必须一层一层地剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,不易调试且影响效率。   

b.解释器模式的使用场景
  • 重复发生的问题可以使用解释器模式。例如,多个应用服务器,每天产生大量的日志,需要对日志文件进行分析处理,由于各个服务器的日志格式是不同的,但是数据要素是相同的,按照解释器的说法就是终结符表达式都是相同的,非终结符表达式就需要定制。
  • 一个简单语法需要解释的场景。

3解释器模式的实例
使用解释器模式完成四则算数运算表达式的计算。

创建算术表达式,抽象解释器角色
ArithmeticExpression.java
package com.eric.行为型模式_Part2.解释器模式.例1;

import com.sun.org.apache.xpath.internal.operations.VariableSafeAbsRef;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 算术表达式,抽象解释器角色
 * @CreateTime 2020-12-15 18:08:12
 */
public interface ArithmeticExpression {
    int interpret(Variables variables);
}
创建变量类
Variable.java
package com.eric.行为型模式_Part2.解释器模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 变量
 * @CreateTime 2020-12-15 18:09:39
 */
public class Variable implements ArithmeticExpression{

    @Override
    public int interpret(Variables variables) {
        return variables.get(this);
    }
}
存储变量值的类
Variables.java
package com.eric.行为型模式_Part2.解释器模式.例1;

import java.util.HashMap;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 使用map存储各个变量的值
 * @CreateTime 2020-12-15 18:10:42
 */
public class Variables {
    HashMap<Variable,Integer> v = new HashMap<Variable,Integer>();
    public void put(Variable variable , int value)
    {
        v.put(variable,value);
    }

    public int get(Variable variable)
    {
        return v.get(variable);
    }
}
创建抽象表达式的4种解析器
Plus.java
package com.eric.行为型模式_Part2.解释器模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 加法
 * @CreateTime 2020-12-15 18:13:28
 */
public class Plus implements ArithmeticExpression {
    ArithmeticExpression left;
    ArithmeticExpression right;

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

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) + right.interpret(variables);
    }
}
Substract.java
package com.eric.行为型模式_Part2.解释器模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 减法
 * @CreateTime 2020-12-15 18:16:45
 */
public class Subtract implements ArithmeticExpression{
    ArithmeticExpression left;
    ArithmeticExpression right;
    public Subtract(ArithmeticExpression left,ArithmeticExpression right)
    {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) - right.interpret(variables);
    }
}
Multiply.java
package com.eric.行为型模式_Part2.解释器模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 乘法
 * @CreateTime 2020-12-15 18:18:35
 */
public class Multiply implements ArithmeticExpression {
    ArithmeticExpression left;
    ArithmeticExpression right;
    public Multiply(ArithmeticExpression left,ArithmeticExpression right)
    {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) * right.interpret(variables);
    }
}
Division.java
package com.eric.行为型模式_Part2.解释器模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 除法
 * @CreateTime 2020-12-15 18:19:30
 */
public class Division implements ArithmeticExpression {
    ArithmeticExpression left;
    ArithmeticExpression right;
    public Division(ArithmeticExpression left,ArithmeticExpression right)
    {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) / right.interpret(variables);
    }
}
客户端类
ClientDemo.java
package com.eric.行为型模式_Part2.解释器模式.例1;

/**
 * @author Eric
 * @ProjectName my_design_23
 * @description 客户端
 * @CreateTime 2020-12-15 18:20:20
 */
public class ClientDemo {
    public static void main(String[] args) {
        Variables v = new Variables();

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

        v.put(x,10);
        v.put(y,20);
        v.put(z,30);

        //计算 x*(y+z/x) - x
        // 10*(20+30/10) - 10 = 220
       ArithmeticExpression e = new Subtract(
                new Multiply(x,
                        new Plus(y,
                                new Division(z,x))),x);
        System.out.println(e.interpret(v));
    }
}
测试结果





只要你不停下来,慢一点也没关系。
原文地址:https://www.cnblogs.com/zyl-0110/p/14751007.html