news 2026/8/27 19:31:55

设计模式[15]——解释器模式一分钟彻底说透

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
设计模式[15]——解释器模式一分钟彻底说透

设计模式[15]——解释器模式(Interpreter)一分钟彻底说透(C++版·软件领域真实例子)

一句话定义

给定一个语言(语法规则),定义它的文法表示,并定义一个解释器来解释和执行该语言中的句子。

最狠的比喻(软件人专属)

SQL查询解析器:

  • 用户输入"SELECT name FROM users WHERE age > 30"
  • 解释器把字符串解析成抽象语法树(AST)
  • 然后遍历树执行:筛选、投影、过滤
    客户端只管写SQL,完全不知道底层怎么解析执行。

GoF原版解释器很冷门,因为它通常只用于自定义小型语言/DSL(领域特定语言),大项目里往往用现成解析器(如ANTLR、Boost.Spirit),但理解它能让你看懂所有表达式引擎的原理。

为什么需要它?(坏味道瞬间爆炸)

不用解释器,你会这样写:

if(input=="A and B"){/* 手动解析 */}elseif(input=="A or (B and C)"){/* 嵌套if爆炸 */}// 新增一种语法?所有代码全改,寄!
和之前模式彻底分清(10秒表)
项目命令(Command)责任链(Chain)解释器(Interpreter)
核心意图操作封装成对象请求沿链找处理者定义语法规则并解释执行
输入单个命令对象单个请求一段“句子”(字符串/表达式)
处理方式执行/撤销传递/终止递归遍历语法树执行
典型场景撤销重做、宏命令中间件、审批规则引擎、SQL、表达式计算器
口号“命令即对象”“传下去,直到有人接”“语法树里走一遭”
真实软件例子:简单布尔表达式解释器(规则引擎常见)
#include<iostream>#include<memory>#include<string>#include<map>usingnamespacestd;// 上下文(携带变量值)structContext{map<string,bool>variables;};// 1. 抽象表达式(所有节点共用接口)classExpression{public:virtual~Expression()=default;virtualboolinterpret(constContext&ctx)const=0;};// 2. 终结符表达式(变量)classVariable:publicExpression{string name;public:explicitVariable(string n):name(move(n)){}boolinterpret(constContext&ctx)constoverride{autoit=ctx.variables.find(name);returnit!=ctx.variables.end()&&it->second;}};// 3. 非终结符表达式(运算符)classAndExpression:publicExpression{unique_ptr<Expression>left,right;public:AndExpression(unique_ptr<Expression>l,unique_ptr<Expression>r):left(move(l)),right(move(r)){}boolinterpret(constContext&ctx)constoverride{returnleft->interpret(ctx)&&right->interpret(ctx);}};classOrExpression:publicExpression{unique_ptr<Expression>left,right;public:OrExpression(unique_ptr<Expression>l,unique_ptr<Expression>r):left(move(l)),right(move(r)){}boolinterpret(constContext&ctx)constoverride{returnleft->interpret(ctx)||right->interpret(ctx);}};classNotExpression:publicExpression{unique_ptr<Expression>expr;public:explicitNotExpression(unique_ptr<Expression>e):expr(move(e)){}boolinterpret(constContext&ctx)constoverride{return!expr->interpret(ctx);}};
客户端:构建并解释表达式树
intmain(){// 构建表达式:(isAdmin and isActive) or (isGuest and not isBanned)autoisAdmin=make_unique<Variable>("isAdmin");autoisActive=make_unique<Variable>("isActive");autoisGuest=make_unique<Variable>("isGuest");autoisBanned=make_unique<Variable>("isBanned");autoadminAccess=make_unique<AndExpression>(move(isAdmin),move(isActive));autoguestAccess=make_unique<AndExpression>(move(isGuest),make_unique<NotExpression>(move(isBanned)));autofinalExpr=make_unique<OrExpression>(move(adminAccess),move(guestAccess));// 测试不同上下文Context ctx1{{"isAdmin",true},{"isActive",true}};// 管理员cout<<"管理员权限: "<<finalExpr->interpret(ctx1)<<endl;// trueContext ctx2{{"isGuest",true},{"isBanned",false}};// 正常游客cout<<"正常游客权限: "<<finalExpr->interpret(ctx2)<<endl;// trueContext ctx3{{"isGuest",true},{"isBanned",true}};// 被禁游客cout<<"被禁游客权限: "<<finalExpr->interpret(ctx3)<<endl;// false}

输出:

管理员权限: 1 正常游客权限: 1 被禁游客权限: 0
C++ 真实项目里无处不在(虽然不直接叫Interpreter)
  • 规则引擎:Drools/Jess的布尔规则 → 解释器模式
  • 表达式计算:Cron表达式解析、数学表达式求值(muParser)
  • 查询语言:小型SQL子集、JSONPath、XPath
  • 脚本引擎:Lua/C++绑定、配置文件的条件判断
  • Boost.Spirit:强大解析器生成器(本质是解释器模式的高级实现)
经典坑 & 正确姿势
  • 解释器模式适合简单语法,复杂语言用解析器生成器(ANTLR、yacc)
  • 每种语法规则对应一个类 → 类爆炸风险(用组合而非继承可缓解)
  • 性能要求高时,解释一次后缓存AST
终极口诀(规则引擎开发者专属)

“语法规则变树状,解释器里走一遭;
布尔SQL随便写,动态执行真牛逼!”

刻在DNA里的一句话

当你需要实现一个自定义的简单语言/表达式/规则(布尔逻辑、查询、配置条件),且希望灵活解释执行时,
立刻上解释器模式——把语法转成对象树,递归解释,想怎么玩都行!

现在,解释器模式(GoF里最冷门但最有逼格的一个)彻底说透了!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 10:24:49

边缘计算场景:轻量级MGeo服务部署方案

边缘计算场景&#xff1a;轻量级MGeo服务部署方案 在物联网项目中&#xff0c;经常需要在边缘设备上运行地址识别功能&#xff0c;但边缘设备的计算能力往往有限。MGeo作为达摩院与高德联合推出的地理地址自然语言处理模型&#xff0c;能够高效完成地址要素解析、相似度匹配等任…

作者头像 李华
网站建设 2026/8/22 5:32:51

LISTAGG vs 传统方法:字符串聚合效率提升300%

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个性能对比测试&#xff0c;比较Oracle中三种字符串聚合方法&#xff1a;1) LISTAGG函数 2) 使用游标和循环 3) XML PATH方法。要求&#xff1a;a) 生成测试数据表(10000条记…

作者头像 李华
网站建设 2026/8/21 17:58:13

如何用AI快速诊断TLS客户端凭据错误10013

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个TLS错误诊断工具&#xff0c;能够自动检测系统环境&#xff1a;1. 扫描Windows注册表中SCHANNEL相关配置项 2. 检查本地证书存储的权限设置 3. 验证系统加密服务提供程序(…

作者头像 李华
网站建设 2026/8/22 6:11:38

弹性计算实践:应对地址处理高峰期的技巧

弹性计算实践&#xff1a;应对地址处理高峰期的技巧 在电商业务中&#xff0c;地址校验服务是一个典型的"潮汐型"业务场景。促销期间订单量激增&#xff0c;地址校验请求可能增长10倍以上&#xff0c;而平时资源又大量闲置。本文将分享如何利用弹性计算架构解决这一…

作者头像 李华
网站建设 2026/8/26 7:10:31

从零部署Vue项目到生产环境全流程实录

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 生成一个Vue3项目的生产环境部署方案&#xff0c;要求&#xff1a;1.基于Docker的容器化配置 2.Nginx最优配置模板&#xff08;包含gzip/缓存策略&#xff09; 3.配套的GitHub Act…

作者头像 李华
网站建设 2026/8/23 4:16:59

AI一键搞定IDEA配置TOMCAT,告别繁琐步骤

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请生成一个完整的IntelliJ IDEA配置Tomcat服务器的项目代码&#xff0c;包括必要的XML配置文件和项目结构。要求&#xff1a;1. 使用Tomcat 9.0版本 2. 包含web.xml配置示例 3. 添…

作者头像 李华