组合模式通过统一接口menucomponent实现菜单项与子菜单的透明操作,叶子menuitem仅存自身信息,容器menugroup持子节点并递归委托行为,支持任意嵌套、免类型判断、易扩展及权限/查找等增强功能。

用组合模式处理树形菜单,核心是让菜单项(叶子)和子菜单(容器)实现同一接口,客户端无需判断类型就能统一操作——比如遍历、渲染或查找。
菜单结构要先定义统一接口
所有菜单节点都实现同一个抽象类或接口,比如 MenuComponent:
- 声明通用行为:display()、getName()、getOrder() 等
- 为容器节点预留 add()、remove()、getChild() 方法(叶子节点可抛 UnsupportedOperationException)
- 避免在客户端用 instanceof 判断类型,这是组合模式要消除的痛点
区分叶子与容器两类实现
MenuItem(叶子)只存自身信息,不持子节点:
- 例如:首页、关于我们、联系我们,点击直接跳转
- display() 直接输出带缩进的名称和 URL
MenuGroup(容器)持有子节点列表,并递归委托行为:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- add(MenuComponent child) 把 MenuItem 或另一个 MenuGroup 加入 children 列表
- display(int depth) 先输出自身名,再对每个 child 调用 child.display(depth + 1)
- 支持嵌套任意层级,比如「产品」→「Web 端」→「控制台」
客户端操作变得极简
构建菜单时只和 MenuComponent 打交道:
- root.add(new MenuItem("首页", "/"))
- MenuGroup product = new MenuGroup("产品");
product.add(new MenuItem("移动端", "/mobile"));
product.add(new MenuItem("桌面端", "/desktop"));
root.add(product); - 最终调用 root.display(0),自动完成整棵树的深度优先渲染
后续扩展也轻松:新增「用户中心」子菜单?只需 new MenuGroup(...) 并 add 进去,不用改任何已有逻辑。
额外增强点可按需加
真实项目中常补充这些能力:
- 通过 path 字符串(如 "/product/mobile")快速 find() 对应节点
- 给 MenuComponent 加 isHidden() 或 hasPermission() 方法,统一控制可见性与权限
- 序列化时用 @JsonTypeInfo 注解区分类型,保留 JSON 中的结构语义
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










