鹰潭市网站建设_网站建设公司_测试工程师_seo优化
2026/1/8 11:02:03 网站建设 项目流程

设计模式[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里最冷门但最有逼格的一个)彻底说透了!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询