当前位置: 首页 > news >正文

Java 23 种设计模式:从踩坑到精通 | 番外:组合 vs 解释器 —— 结构树 vs 计算树

Java 23 种设计模式:从踩坑到精通 | 番外:组合 vs 解释器 —— 结构树 vs 计算树

摘要:组合模式和解释器模式都用到了树形结构,但组合模式的树是“结构树”——叶子与容器行为统一,客户端一致处理;解释器模式的树是“计算树”——每种节点有独立的求值逻辑,通过递归计算得出结果。本文从文件系统管理器和四则运算计算器两个场景出发,结合代码对比、UML 分析和 JDKPattern、Spring SpEL 源码,帮你彻底分清这对“树形结构型”模式。

🗺️本文阅读地图(3 分钟速览)

  • 为什么文件系统是组合模式,表达式求值是解释器模式?
  • UML 对比:统一操作 vs 递归求值
  • 手写文件系统管理器 vs 四则运算计算器,看代码感受差异
  • 组合模式中的operation()和解释器中的interpret()本质区别
  • 面试必问:“组合和解释器都用了树,到底有什么区别?”

📖《Java 23 种设计模式:从踩坑到精通》
开篇:系列介绍与目录 |当前:番外 · 组合 vs 解释器
🔗 返回系列总目录


文章目录

  • Java 23 种设计模式:从踩坑到精通 | 番外:组合 vs 解释器 —— 结构树 vs 计算树
    • 1. 从“文件系统”和“四则运算”两个场景说起
      • 1.1 场景一:文件系统管理器(组合模式)
      • 1.2 场景二:四则运算计算器(解释器模式)
      • 1.3 关键差异已浮现
    • 2. UML 对比
    • 3. 三大核心区别
    • 4. JDK 源码深度对比
      • 4.1 AWT 组件树(组合模式)
      • 4.2 Java 正则表达式(解释器模式)
    • 5. 组合模式可以作为解释器模式的“基础结构”
    • 6. 面试必问 + 追问连环炮
    • 🧭 《Java 23 种设计模式:从踩坑到精通》快速导航

1. 从“文件系统”和“四则运算”两个场景说起

1.1 场景一:文件系统管理器(组合模式)

假设你在开发一个文件管理系统,需要展示文件夹和文件的层级结构。文件夹里可以有文件,也可以有子文件夹。你需要递归展示整个目录树,但不管是文件还是文件夹,对客户端来说最好能统一操作

// 组合模式:统一处理叶子(文件)和容器(文件夹)FileSystemNoderoot=newFolderNode("root");FileSystemNodedocs=newFolderNode("docs");FileSystemNodefile1=newFileNode("readme.txt");FileSystemNodefile2=newFileNode("image.png");root.add(docs);docs.add(file1);docs.add(file2);// 客户端不用区分文件和文件夹,统一调用 show()root.show(0);// 输出:// 文件夹:root// 文件夹:docs// 文件:readme.txt// 文件:image.png

💬白话:客户端只调用show(),不管是文件还是文件夹都照常执行。组合模式的核心是统一叶子与容器的接口,让客户端一致处理。

1.2 场景二:四则运算计算器(解释器模式)

现在你要实现一个表达式计算器,能够解析并计算a + b - c这样的表达式。变量abc是叶子节点,+-是运算符节点。你需要根据语法规则递归求值

// 解释器模式:构建语法树,递归求值Contextctx=newContext();ctx.setVariable("a",10);ctx.setVariable("b",5);ctx.setVariable("c",2);// 构建语法树:a + b - cExpressionexpression=newSubtract(newAdd(newVariable("a"),newVariable("b")),newVariable("c"));intresult=expression.interpret(ctx);System.out.println("a + b - c = "+result);// 13

💬白话Add节点和Subtract节点各自有自己的求值逻辑,Variable节点直接取值。每种节点的interpret()行为完全不同。解释器模式的核心是每种节点有独立的计算逻辑,通过递归得出最终结果

1.3 关键差异已浮现

  • 组合模式:文件和文件夹的show()行为相似——都是展示自己,文件夹多了遍历子节点;
  • 解释器模式Add.interpret()做加法,Subtract.interpret()做减法,Variable.interpret()取值——行为完全不同

2. UML 对比

3. 三大核心区别

对比维度组合模式解释器模式
树的性质结构树——表示部分-整体层次关系计算树——表示语法规则和求值逻辑
节点行为operation()统一——叶子与容器行为相似interpret()各不相同——每种节点求值逻辑不同
是否管理子节点✅ 容器有add()/remove()❌ 节点不暴露管理方法
客户端操作调用顶层节点的方法,递归遍历整棵树调用顶层节点的interpret(),递归计算出结果
典型应用文件系统、组织架构、AWT 组件树四则运算、正则表达式、Spring SpEL

4. JDK 源码深度对比

4.1 AWT 组件树(组合模式)

// AWT 中,Panel 是容器,Button 是叶子,都继承自 Component// add() 方法在容器中管理子组件,paint() 递归渲染整棵组件树Panelpanel=newPanel();Buttonbtn=newButton("点击");panel.add(btn);// 容器管理子组件panel.paint(graphics);// 递归渲染所有子组件

为什么是组合模式?

  • ButtonPanel都继承自Component,接口统一;
  • Panel通过add()管理子组件,Button没有子组件;
  • 调用paint()时,Panel递归调用所有子组件的paint()——行为一致。

4.2 Java 正则表达式(解释器模式)

// Pattern 内部将正则表达式编译为一棵语法树Patternpattern=Pattern.compile("a(b|c)*d");Matchermatcher=pattern.matcher("abcd");booleanmatches=matcher.matches();

为什么是解释器模式?

  • 正则表达式a(b|c)*d被解析为一棵语法树;
  • abcd是终结符(字符字面量),|*是非终结符(运算符);
  • 匹配时递归遍历语法树,每种节点(字符、选择、重复)执行不同的匹配逻辑——行为各不相同

5. 组合模式可以作为解释器模式的“基础结构”

解释器模式通常建立在组合模式之上——语法树本身就是一种树形结构,非终结符节点包含子表达式,这与组合模式的容器-叶子结构高度相似。

对比维度组合模式解释器模式
关注点结构的组织方式结构的计算逻辑
组合关系独立使用通常建立在组合模式之上
面试常见问法“如何统一处理树形结构?”“如何设计一个表达式解析器?”

💡一句话总结:组合模式负责“搭架子”(树形结构),解释器模式负责“填逻辑”(每种节点的计算规则)。Spring SpEL 就是先构建组合树,再递归求值的典型代表。

6. 面试必问 + 追问连环炮

基础必问

  • 组合模式和解释器模式都用到了树,有什么区别?
    👉 组合关注“结构统一”——叶子与容器行为一致,客户端统一操作;解释器关注“递归求值”——每种节点有不同的计算逻辑。
  • 什么时候用组合?什么时候用解释器?
    👉 需要统一处理树形结构(文件系统、菜单)→ 组合;需要定义语法规则并求值(表达式、规则引擎)→ 解释器。

面试官追问

  • “解释器模式和组合模式能配合使用吗?”
    👉 可以。解释器模式的语法树通常建立在组合模式之上——用组合模式管理树结构,用解释器模式实现每个节点的求值逻辑。Spring SpEL 就是这样做的。
  • “为什么复杂语法不推荐解释器模式?”
    👉 因为每个语法规则都要对应一个类,类数量会爆炸(类膨胀问题);递归求值性能远低于直接编译。此时应用 ANTLR、JavaCC 等专业解析器生成工具。
  • “组合模式中,如果只想遍历叶子节点怎么办?”
    👉 在 Component 接口中定义isLeaf()方法,或使用访问者模式对不同节点类型分别处理。

🎉恭喜:如果你能立刻画出文件系统的树形结构和四则运算的语法树,并说出“组合关注结构统一,解释器关注递归求值”,你已经掌握了这两棵树最核心的区别。

💡延伸阅读:本文是组合模式与解释器模式的深度对比。如果你想先了解每种模式的完整原理、UML、代码实现和面试题,可以先阅读正篇——组合模式:树形结构处理,部分与整体一视同仁 和 解释器模式:自己动手写一个小语言解释器,再回来看这篇对比,效果更佳。

🧭 《Java 23 种设计模式:从踩坑到精通》快速导航

  • 开篇:系列介绍与目录
  • 当前:番外 · 组合 vs 解释器 —— 结构树 vs 计算树(你在这里)
  • 📖 延伸阅读:组合模式正篇 | 解释器模式正篇
  • 创建型模式汇总
  • 结构型模式汇总
  • 行为型模式汇总

🔔 关注《Java 23 种设计模式:从踩坑到精通》,用 25 篇文章彻底吃透设计模式。
📦福利预告:全系列代码及 UML 源码将在完结时统一打包开放,点击「关注」「收藏」第一时间获取。

📌 除了设计模式,我也在深挖智能物流实战(WMS、托盘调度、机器学习落地)。欢迎点击头像,看看专栏 《出版社物流WMS智能调度实战》。技术相通,思路可鉴。

http://www.cnnetsun.cn/news/3410875.html

相关文章:

  • 深入解析SM320C6748-HIREL引脚复用:从配置表到工程实践
  • 1846_安全SPI:从协议演进到车规级安全通信的实践解析
  • 基于西门子plc 博图1200 基于西门子plc的药片自动装瓶12(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • JLU吉林大学软件学院《计算机网络》核心考点与真题实战解析(2020级适用)
  • PostureGuard:基于智能眼镜的AI坐姿守护助手
  • 从“未能加载System.Net.Http”错误出发:深入解析.NET程序集绑定与版本冲突
  • 【C++提高】高精度加法
  • COST231-WI模型参数解析与MATLAB仿真实践
  • AI语音合成技术演进:从Tacotron到端到端神经网络声码器
  • 从教育焦虑到个性化学习:破解孩子学习动力的密码
  • 从选型到焊接:阻容封装尺寸速查与实战应用指南
  • K8s PV 动态供给的陷阱:StorageClass 参数配错后的连锁反应
  • 智能技术架构文档自动生成:保持文档与代码同步
  • DirectX Repair增强版,DLL缺失一键修复+0xc000007b解决,绿色版下载
  • AI 智能插座智能功率 高集成度 完整选型方案
  • Excel无分支逻辑:用数学运算替代IF提升性能与可维护性
  • 实时响应延迟飙升210ms?(频率惩罚与temperature的量子纠缠效应:GPU显存级性能压测报告)
  • 阿里云百炼 GLM-5.2 Fast mode 降价 20% 今日生效 + 主流大模型 API 价格横评与 Fast mode 选型
  • 渗透测试第一步:信息收集做得好,漏洞挖到老(第五弹·实战侦察篇)
  • 61种农作物叶片病害识别代码包(含数据不均衡修复与Inception-v3训练全流程)
  • 运维Agent的记忆系统设计:短期工作记忆与长期知识库的协同架构与一致性保障
  • 代码可对话:基于LangChain+Chroma的RAG实践指南
  • 房地产中介业务全流程Java系统:客户跟进、房源管理、佣金结算一体化
  • 微信接口接入:如何串起企业的自动化流程?
  • bulk RNA-seq之后,为什么还需要组织原位空间蛋白组观察?
  • SolidWorks_钣金设计5_褶边与折弯
  • C#编写的WinForms人事管理系统源码(含SQL Server数据库脚本与完整界面)
  • 新中大银色快车SE财务软件高频问题排查与实战解决指南
  • MATLAB写的线弹性结构动力响应仿真脚本,含悬臂梁算例和时域求解器
  • 玄学时刻:为什么模型周末表现比工作日好