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

文章目录

  • 前言
  • 一、概念
  • 二、核心结构
  • [三、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. 开发中极常用,是处理层级结构的最优解
相关推荐
workflower8 小时前
装备企业的 AI 路线图
人工智能·深度学习·机器学习·设计模式·机器人
geovindu18 小时前
CSharp:Chain of Responsibility Pattern
开发语言·后端·设计模式·c#·.net·责任链模式·行为模式
梓仁沐白20 小时前
【Agent 设计模式】多智能体协作
microsoft·设计模式·php
努力学习的廖同学20 小时前
前端进阶-设计模式
设计模式
workflower2 天前
情境感知系统
人工智能·机器学习·设计模式·自然语言处理·机器人
咖啡八杯2 天前
设计模式中的原则
设计模式·接口隔离原则·里氏替换原则·开闭原则·合成复用原则·单一职责原则
安冬的码畜日常2 天前
【工欲善其事】深入理解 Node.js 带并发上限的异步任务批量执行逻辑
javascript·设计模式·node.js·ai编程·异步编程·并发执行
AI大法师2 天前
一个机场如何被做成 IP 场景:宝可梦机场的设计方法总结
大数据·人工智能·设计模式·新媒体运营
晚安code3 天前
干掉成山的 if-else:工厂造、策略选,一文讲透两个模式的配合
后端·设计模式
workflower3 天前
从幻觉,到现实
人工智能·深度学习·机器学习·设计模式·机器人