• 设计模式-行为型-解释器模式


    描述

    • 对于形式变化比较多的情况下,可以把变化定义成节点,定义一个解释器,去逐步解析节点的合法性,得到最终结果。
    • 比如计算器:1+2+3+4-5,1+2+3-4+5,…
    • 把数字和+ - 定义成节点,由解释器去解析(提取语句规则,抽象成一种语言,然后解析这种语言的含义),得到最终结果。

    定义语法规则:

    • express:表达式( | :表示或的意思)
    • plus:加法表达式
    • minus:减法表达式
    • value:最终结果
    express ::= value | plus | minus
    plus ::= express + express
    minus ::= express - express
    value ::= integer
    
    • 1
    • 2
    • 3
    • 4

    角色

    • 抽象表达式角色:定义解释器的接口,约定规范,提供解析方法:interpret。
    • 终结符表达式角色:抽象表达式子类,用来实现终结符相关操作。如语法规则中的value。
    • 非终结符表达式角色:抽象表达式子类,用来实现非终结符相关操作。如语法规则中的:plus等。
    • 环境角色:定义解释器需要的数据,公共功能,传递所有解释器共享的数据。
    • 客户端:将表达式装换为解释器对象解析的抽象语法树,让解释器解析获得结果。

    实现

    public class Test {
        public static void main(String[] args) {
            Environment environment = new Environment();
            ParameterExpress a = new ParameterExpress("A");
            ParameterExpress b = new ParameterExpress("B");
            ParameterExpress c = new ParameterExpress("C");
            ParameterExpress d = new ParameterExpress("D");
            environment.add(a, 11);
            environment.add(b, 2);
            environment.add(c, 4);
            environment.add(d, 6);
    
            AbstractExpress express = new PlusExpress(new SubtractionExpress(new PlusExpress(a, b), c), d);
            Integer interpret = express.interpret(environment);
            System.out.println(express);
            System.out.println(interpret);
    
        }
    }
    // 抽象表达式
    abstract class AbstractExpress {
        abstract Integer interpret(Environment environment);
    }
    
    // 环境角色,理解成容器,存储具体参数角色
    class Environment {
        // 参数节点
        private Map<ParameterExpress, Integer> parameterExpressIntegerMap = new HashMap<>();
        // 存入数据
        public void add(ParameterExpress parameterExpress, Integer value) {
            parameterExpressIntegerMap.put(parameterExpress, value);
        }
        // 获取数据
        public Integer get(ParameterExpress parameterExpress) {
            return parameterExpressIntegerMap.get(parameterExpress);
        }
    }
    
    // 具体变量角色
    class ParameterExpress extends AbstractExpress {
        // 变量名称
        private String name;
    
        ParameterExpress(String name){ this.name = name;}
        @Override
        Integer interpret(Environment environment) {
        	// 获取变量数据
            return environment.get(this);
        }
    
        @Override
        public String toString() {
            return name;
        }
    }
    // 具体加法表达式
    class PlusExpress extends AbstractExpress {
        // 左边表达式
        private AbstractExpress left;
        // 右边表达式
        private AbstractExpress right;
    
        PlusExpress(AbstractExpress left, AbstractExpress right) {
            this.left = left;
            this.right = right;
        }
    
        @Override
        Integer interpret(Environment environment) {
        	// 加法表达式规则
            return left.interpret(environment) + right.interpret(environment);
        }
    
        @Override
        public String toString() {
            return left + "+" + right;
        }
    }
    // 具体减法表达式
    class SubtractionExpress extends AbstractExpress {
        // 左边表达式
        private AbstractExpress left;
        // 右边表达式
        private AbstractExpress right;
    
        SubtractionExpress(AbstractExpress left, AbstractExpress right) {
            this.left = left;
            this.right = right;
        }
    
        @Override
        Integer interpret(Environment environment) {
        	// 减法表达式规则
            return left.interpret(environment) - right.interpret(environment);
        }
    
        @Override
        public String toString() {
            return left + "-" + right;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    优点

    • 易于扩展和改变表达式规则,表达式规则编写较为符合思考逻辑。符合开闭原则。

    缺点

    • 复杂文法难以维护,每种规则都需要一个类,类个数太多难以管理维护,递归,执行效率较低,调试较麻烦。

    使用场景

    • 当语言的文法较为简单,且执行效率不是问题,简单语法规则重复出现时。
  • 相关阅读:
    数值优化:经典随机优化算法及其收敛性与复杂度分析
    产品经理面试考查的是什么?
    python 获取文件夹中的全部文件
    Program design PACT analysis
    道路标识检测模型更新
    docker-harbor私有仓库
    Win11启动修复无效怎么办
    Nuxt - 实现微信扫码登录功能(SSR 服务端渲染项目植入微信扫码登录功能)超详细完整流程详解及详细代码及注释,附带完整功能源码、常见问题解决方案
    ESP32网络开发实例-将 ESP32 连接到 EMQX Cloud MQTT Broker
    【并联有源电力滤波器】基于pq理论的并联有源电力滤波器(Simulink)
  • 原文地址:https://blog.csdn.net/qq_43630812/article/details/126167395