zoukankan      html  css  js  c++  java
  • 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));
        }
    }
    测试结果





    只要你不停下来,慢一点也没关系。
  • 相关阅读:
    Django各个文件中常见的模块导入
    js模板(template.js)实现页面动态渲染
    Netty 源码 Channel(一)概述
    Netty 源码 NioEventLoop(三)执行流程
    Netty 源码(一)Netty 组件简介
    Netty 源码(二)NioEventLoop 之 Channel 注册
    Java 算法(一)贪心算法
    Netty Reator(三)Reactor 模型
    Netty Reator(二)Scalable IO in Java
    Reactor 模型(一)基本并发编程模型
  • 原文地址:https://www.cnblogs.com/zyl-0110/p/14751007.html
Copyright © 2011-2022 走看看