【设计模式】结构型-组合模式

文章目录

  • 前言
  • 一、概念
  • 二、核心结构
  • [三、Java 代码实现(文件 + 文件夹示例)](#三、Java 代码实现(文件 + 文件夹示例))
    • [1. 抽象组件(Component)](#1. 抽象组件(Component))
    • [2. 叶子节点:文件(Leaf)](#2. 叶子节点:文件(Leaf))
    • [3. 组合节点:文件夹(Composite)](#3. 组合节点:文件夹(Composite))
    • [4. 客户端测试](#4. 客户端测试)
  • 四、组合模式的两种形式
    • [1. 透明模式(本文示例)](#1. 透明模式(本文示例))
    • [2. 安全模式](#2. 安全模式)
  • 五、优缺点
  • 六、应用场景
  • [七、组合模式 VS 外观模式](#七、组合模式 VS 外观模式)
  • 八、总结

前言

在业务系统中,我们经常会遇到**"整体与部分"具有 一致性操作的场景:比如文件与文件夹、菜单与子菜单、部门与员工、订单与订单明细、树形权限等。如果用两套代码分别处理"单个对象"和"组合对象",代码会臃肿、难维护、极易出错。组合模式正是用来解决这类树形结构、整体与部分统一处理**的经典设计模式。


一、概念

组合模式(Composite Pattern) 是一种结构型设计模式 ,核心思想是:
将对象组合成树形结构,以表示"整体-部分"的层次关系,并且让客户端可以统一对待单个对象和组合对象。

简单理解:

  • 叶子节点(Leaf):最小单元,无子节点(如文件、单个员工)
  • 组合节点(Composite):包含子节点,可以是叶子或其他组合(如文件夹、部门)
  • 客户端:不用判断是叶子还是组合,直接调用同一套接口

二、核心结构

  1. Component(抽象组件)
    定义统一接口,叶子和组合都实现它。
  2. Leaf(叶子节点)
    最小单元,没有子节点,实现业务逻辑。
  3. Composite(组合节点)
    包含子节点列表,实现添加/删除/遍历子节点逻辑。
  4. Client(客户端)
    面向 Component 编程,统一调用。

三、Java 代码实现(文件 + 文件夹示例)

以最经典的文件系统为例:

  • 文件(Leaf):不能再包含子节点
  • 文件夹(Composite):可以包含文件或文件夹
  • 统一方法:show() 显示信息

1. 抽象组件(Component)

java 复制代码
public abstract class FileSystemComponent {
    protected String name;

    public FileSystemComponent(String name) {
        this.name = name;
    }

    // 统一展示方法
    public abstract void show();

    // 组合类专用,叶子类空实现或抛异常
    public void add(FileSystemComponent component) {
        throw new UnsupportedOperationException("不支持添加");
    }

    public void remove(FileSystemComponent component) {
        throw new UnsupportedOperationException("不支持删除");
    }
}

2. 叶子节点:文件(Leaf)

java 复制代码
public class File extends FileSystemComponent {

    public File(String name) {
        super(name);
    }

    @Override
    public void show() {
        System.out.println("文件:" + name);
    }
}

3. 组合节点:文件夹(Composite)

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class Folder extends FileSystemComponent {

    private List<FileSystemComponent> children = new ArrayList<>();

    public Folder(String name) {
        super(name);
    }

    @Override
    public void add(FileSystemComponent component) {
        children.add(component);
    }

    @Override
    public void remove(FileSystemComponent component) {
        children.remove(component);
    }

    @Override
    public void show() {
        System.out.println("文件夹:" + name);
        // 递归展示所有子节点
        for (FileSystemComponent child : children) {
            child.show();
        }
    }
}

4. 客户端测试

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 叶子
        FileSystemComponent file1 = new File("笔记.txt");
        FileSystemComponent file2 = new File("图片.jpg");
        FileSystemComponent file3 = new File("设计稿.psd");

        // 组合
        FileSystemComponent folder1 = new Folder("学习资料");
        folder1.add(file1);
        folder1.add(file2);

        FileSystemComponent folder2 = new Folder("工作文档");
        folder2.add(file3);
        folder2.add(folder1); // 嵌套组合

        // 统一调用 show()
        folder2.show();
    }
}

输出:

复制代码
文件夹:工作文档
设计稿.psd
文件夹:学习资料
笔记.txt
图片.jpg

四、组合模式的两种形式

1. 透明模式(本文示例)

  • Component 定义 add/remove/show
  • 叶子也必须实现,默认抛异常或空实现
  • 优点:客户端完全不用区分叶子/组合,真正透明
  • 缺点:叶子有多余方法,违反单一职责

2. 安全模式

  • Component 只定义公共方法(如 show)
  • add/remove 只在 Composite 中定义
  • 优点:安全,不会调用错方法
  • 缺点:客户端要判断类型,失去统一处理优势

实际开发:透明模式更常用。


五、优缺点

优点

  1. 统一处理整体与部分
    客户端不用判断是单个对象还是组合对象。
  2. 完美适配树形结构
    菜单、组织架构、权限、目录、订单套餐等天然适配。
  3. 扩展性极强
    新增叶子/组合类不影响旧代码,符合开闭原则。
  4. 简化客户端代码
    不用写大量 if-else 判断类型。

缺点

  1. 设计略复杂,需要区分 Leaf 和 Composite
  2. 若层次太深,递归遍历可能影响性能
  3. 透明模式会让叶子拥有不该有的方法(add/remove)

六、应用场景

凡是树形结构、整体与部分能统一操作的场景,都用组合模式:

  1. 文件系统:文件 + 文件夹
  2. 菜单系统:菜单、子菜单、菜单项
  3. 组织架构:公司 → 部门 → 小组 → 员工
  4. 权限系统:角色 → 权限组 → 权限点
  5. 订单/购物车:订单 → 商品组 → 商品
  6. UI 组件树:页面 → 容器 → 组件

经典源码应用:

  • Java AWT / Swing 组件树(Container + Component)
  • MyBatis 动态 SQL 节点(SqlNode 组合)
  • Spring Security 权限配置

七、组合模式 VS 外观模式

组合模式 外观模式
整体-部分树形结构 复杂子系统统一入口
递归、嵌套、层次 一层封装、转发
客户端统一处理单个/组合 客户端只访问入口,不接触子系统
  • 组合:内部结构是树形,强调"部分+整体一致"
  • 外观:内部结构复杂,强调"简化入口"

八、总结

  1. 组合模式 = 树形结构 + 整体与部分统一处理
  2. 核心角色:Component(抽象)、Leaf(叶子)、Composite(组合)
  3. 核心价值:客户端不用判断类型,统一调用
  4. 最适合:菜单、文件、组织架构、权限、订单等树形结构
  5. 开发中极常用,是处理层级结构的最优解
相关推荐
砍光二叉树4 小时前
【设计模式】结构型-享元模式
设计模式·享元模式
电子科技圈4 小时前
SmartDV展示汽车IP解决方案以赋能智驾创芯并加速规模化普及
嵌入式硬件·设计模式·硬件架构·软件工程·软件构建·设计规范
砍光二叉树5 小时前
【设计模式】结构型-桥接模式
设计模式·桥接模式
姓蔡小朋友5 小时前
Agent Skill设计模式
开发语言·javascript·设计模式
砍光二叉树5 小时前
【设计模式】结构型-外观模式
设计模式·外观模式
zhaoshuzhaoshu6 小时前
设计模式6大原则详细对比(含场景举例)
设计模式·设计语言
砍光二叉树6 小时前
【设计模式】行为型-观察者模式
java·观察者模式·设计模式
泯仲19 小时前
Ragent项目7种设计模式深度解析:从源码看设计模式落地实践
java·算法·设计模式·agent
WarrenMondeville1 天前
1.Unity面向对象-单一职责原则
unity·设计模式·c#