【设计模式】组合模式(Composite)详解

文章目录

    • [1. 引言:目录结构是怎么设计出来的?](#1. 引言:目录结构是怎么设计出来的?)
    • [2. 什么是组合模式](#2. 什么是组合模式)
      • [GoF 定义](#GoF 定义)
    • [3. 组合模式的核心思想](#3. 组合模式的核心思想)
    • [4. 组合模式的结构](#4. 组合模式的结构)
    • [5. 示例:文件系统](#5. 示例:文件系统)
      • [5.1 抽象组件](#5.1 抽象组件)
      • [5.2 叶子节点(文件)](#5.2 叶子节点(文件))
      • [5.3 容器节点(文件夹)](#5.3 容器节点(文件夹))
      • [5.4 客户端使用](#5.4 客户端使用)
    • [6. 组合模式的优点](#6. 组合模式的优点)
    • [7. 组合模式的缺点](#7. 组合模式的缺点)
    • [8. 组合 vs 装饰 vs 外观](#8. 组合 vs 装饰 vs 外观)
    • [9. JDK 中的组合模式](#9. JDK 中的组合模式)
      • [Java Swing](#Java Swing)
    • [10. 适用场景](#10. 适用场景)
    • [11. 一个经典误区](#11. 一个经典误区)
    • 参考

1. 引言:目录结构是怎么设计出来的?

在操作系统中,你会看到这样的结构:

plain 复制代码
/root
   ├── bin
   ├── usr
   │     ├── local
   │     └── share
   └── file.txt

这里有两种对象:

  • 目录(可以包含子目录和文件)
  • 文件(不能再包含东西)

但对用户来说:

它们都可以被"打开、删除、显示大小"。

如何让"文件"和"文件夹"在使用时看起来是一样的?

这正是组合模式要解决的问题。

只要你在设计"树形结构",就该想到组合模式。


2. 什么是组合模式

GoF 定义

将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

详细解释:组合模式,又名部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

一句话理解:

把"整体"和"部分"统一对待。


3. 组合模式的核心思想

组合模式解决的是:

如何让"容器对象"和"叶子对象"使用同一套接口。

它的本质是:

  • 把树结构隐藏在内部
  • 对外只暴露统一的操作接口

4. 组合模式的结构

组合模式包含三个核心角色:

  1. Component(抽象构件)

定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。

  1. Leaf(叶子节点)

叶子节点对象,其下再无分支,是系统层次遍历的最小单位。

  1. Composite(容器节点)

定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。Composite本身就有合成的意思。


5. 示例:文件系统

5.1 抽象组件

java 复制代码
public abstract class FileComponent {
    public abstract void show();
}

5.2 叶子节点(文件)

java 复制代码
public class File extends FileComponent {

    private String name;

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

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

5.3 容器节点(文件夹)

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

public class Folder extends FileComponent {

    private String name;
    private List<FileComponent> children = new ArrayList<>();

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

    public void add(FileComponent component) {
        children.add(component);
    }

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

5.4 客户端使用

java 复制代码
File file1 = new File("a.txt");
File file2 = new File("b.txt");

Folder folder = new Folder("docs");
folder.add(file1);
folder.add(file2);

Folder root = new Folder("root");
root.add(folder);

root.show();

输出结果:

plain 复制代码
文件夹:root
文件夹:docs
文件:a.txt
文件:b.txt

客户端并不关心它是文件还是文件夹。


6. 组合模式的优点

  1. 客户端使用简单
  2. 天然适合树结构
  3. 易于增加新节点类型
  4. 符合开闭原则

7. 组合模式的缺点

  1. 叶子和容器接口可能不完全一致
  2. 对类型限制不严格
  3. 容易被误用

8. 组合 vs 装饰 vs 外观

模式 关注点
组合 层级结构
装饰 功能叠加
外观 统一入口

9. JDK 中的组合模式

Java Swing

java 复制代码
Container → JPanel → JButton

窗口、面板、按钮都继承自 Component,可以被统一操作。


10. 适用场景

适合使用

  • 需要表示树形结构
  • 想让整体和部分操作一致
  • 目录、菜单、组织架构

组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多级目录呈现等树形结构数据的操作。

不适合使用

  • 结构不是层次型
  • 节点类型差异太大

11. 一个经典误区

组合模式不是为了"套娃",而是为了"统一接口"。


参考

组合模式 | 菜鸟教程

《图解设计模式》

组合 - Java教程 - 廖雪峰的官方网站

组合设计模式

相关推荐
深盾科技_Virbox17 分钟前
软件交付保护如何从加壳走向代码虚拟化
java·python·安全
学计算机的计算基19 分钟前
二叉树算法下篇:递归核心技巧与高频面试题详解
java·笔记·算法
Liquad Li33 分钟前
Salesforce高级开发面试题
java·网络·面试·crm·salesforce
Zhou1411361 小时前
Java常见面试题7
java·开发语言
带刺的坐椅1 小时前
代码审查 Agent Harness 实战:AI 自动 Code Review
java·ai·llm·agent·solon·soloncode·harness
可儿·四系桜1 小时前
经纬度转北斗网格位置码(非极地区域,编码篇)
java·物联网
唐青枫1 小时前
Java ActiveMQ 实战指南:从 JMS 队列、主题到 Spring Boot 消息处理
java
码兄科技9 小时前
Java AI智能体开发实战:从零构建智能对话系统指南
java·开发语言·人工智能
折哥的程序人生 · 物流技术专研9 小时前
第8篇:六大设计原则在工厂模式中的体现
java·设计模式·设计原则·工厂模式·编程进阶·扩充系列