当前位置: 首页 > 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.jsqmd.com/news/1196715/

相关文章:

  • 2026年7月最新烟台百达翡丽官方售后服务热线与网点地址查询 - 百达翡丽官方售后中心
  • C++模块解耦:变量变更方案对比与实战选型指南
  • 对外接口层
  • 长沙天心区测、除甲醛|维小达|CMA甲醛检测、新房除醛、工装除醛、板材源头除醛、全屋空气净化、老旧翻新祛异味、居家商用一站式空气养护服务 - 一点传媒
  • Mac上通过Homebrew与pip3一站式部署Jupyter生态
  • DeerFlow 深度解析:如何用多智能体架构精准答题
  • 2023年全国电赛H题信号分离装置:从加法器到DDS的硬件实现与频谱分析实战
  • 多维度评估 + 动态人才画像,精准定位高潜人才补齐组织能力短板
  • 《全域数学·工程应用大典》113–200讲完整总目录
  • 2026风扇及散热配件外贸独立站搭建公司怎么选?八项结构化评估指南,含零代码SAAS,源码定制交付
  • 2026年银川合同律师推荐怎么选?看这五点关键不踩雷 - 本地品牌推荐
  • 飞行动力学 - 纵向静稳定性剖析:从部件贡献到设计权衡
  • 2026宜春大冰块厂家回头客榜单推荐:哪家更靠谱? - 热点咨讯
  • 攻克Android 7+ HTTPS抓包壁垒:夜神模拟器Root权限与Charles证书系统级部署实战
  • 咸安黄金回收实测记录,正规老店全城免费上门 - 华金汇黄金回收
  • 电机驱动实战-基于STM32的直流有刷电机H桥控制与保护电路设计
  • 长沙芙蓉区测、除甲醛|维小达|CMA甲醛检测、新房除醛、工装除醛、板材源头除醛、全屋空气净化、老旧翻新祛异味、居家商用一站式空气养护服务 - 一点传媒
  • 2026 团风黄金回收星级深度测评|深耕 30 年本土合规老店,全县 24 小时免费上门无任何隐形扣费 - 华金汇黄金回收
  • 劳力士中国官方售后服务中心|地址与联系电话权威信息声明(2026年7月最新) - 劳力士服务中心
  • Obsidian五种同步策略详解:怎么根据设备角色设置仅发送、仅接收和双向同步
  • 2026 年选 SEO公司前必读:7 个“一票否决”红线,踩中一条直接拉黑+避坑指南 - GEO优化
  • 百达翡丽中国官方售后服务中心|服务电话及全部地址权威信息通告(2026年7月更新) - 百达翡丽官方售后中心
  • DSP C2000 F28002x 数字电源实战:基于SysConfig的ePWM与CMPSS联动保护配置
  • 2026 年当下,优秀的G657A1光纤源头厂家哪家权威,揭秘:为什么你的网络升级没用? - 领域鉴赏官
  • 鸿蒙 ArkTS 实战:Camping Spot Favorites 从出行记录到状态反馈完整解析
  • 篆刻印章文玩石料线上怎么卖?小程序商城高粘性运营思路,含零代码SAAS、AI编程、源码定制交付
  • 原生嵌入主流办公协同工具,打造轻量化员工自助咨询入口
  • 2026 京山卖金完整测评|本地三十年合规回收老店,城乡上门无任何隐藏收费 - 华金汇黄金回收
  • PyTorch模型服务化实战:从Notebook到生产级TorchServe部署
  • 宝玑中国官方售后服务中心|服务热线及网点地址权威信息通知(2026年7月更新) - 亨得利钟表维修中心