【玩转23种Java设计模式】结构型模式篇:组合模式

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。
汇总目录链接:【玩转23种Java设计模式】学习目录汇总整理

文章目录

一、简介

组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示"部分-整体"的层次关系。其核心思想是通过统一接口处理叶子对象(单个元素)和组合对象(容器元素),使客户端无需区分操作的是单个对象还是整个组合结构。

核心角色:

  • Component:声明组合对象的通用接口
  • Leaf:叶子节点(无子节点)
  • Composite:容器节点(包含子组件集合)

二、实例

假设需要构建文件系统,包含文件夹(组合对象)和文件(叶子对象)。

1、抽象组件

java 复制代码
interface FileSystemComponent {
    void display(int indent);
    long getSize();
}

2、叶子节点:文件

java 复制代码
class File implements FileSystemComponent {
    private String name;
    private long size;

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

    @Override
    public void display(int indent) {
        System.out.println(" ".repeat(indent) + "📄 " + name + " (" + size + "KB)");
    }

    @Override
    public long getSize() { return size; }
}

3、组合节点:文件夹

java 复制代码
class Directory implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> children = new ArrayList<>();

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

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

    @Override
    public void display(int indent) {
        System.out.println(" ".repeat(indent) + "📁 " + name);
        children.forEach(child -> child.display(indent + 2));
    }

    @Override
    public long getSize() {
        return children.stream().mapToLong(FileSystemComponent::getSize).sum();
    }
}

4、客户端使用

java 复制代码
public class Demo {
    public static void main(String[] args) {
        Directory root = new Directory("Root");
        
        Directory documents = new Directory("Documents");
        documents.add(new File("resume.pdf", 256));
        documents.add(new File("notes.txt", 128));
        
        Directory images = new Directory("Images");
        images.add(new File("photo1.jpg", 2048));
        
        root.add(documents);
        root.add(images);
        
        root.display(0);
        System.out.println("Total size: " + root.getSize() + "KB");
    }
}

输出示例:

📁 Root

📁 Documents

📄 resume.pdf (256KB)

📄 notes.txt (128KB)

📁 Images

📄 photo1.jpg (2048KB)

Total size: 2432KB

三、总结

1、优点

  • 简化客户端代码:统一处理单个对象与组合结构。
  • 高扩展性:新增组件类型无需修改现有代码。
  • 天然支持递归结构:方便实现树形操作(如遍历、统计)。

2、缺点

  • 类型安全性问题:需要运行时类型检查。
  • 接口设计难度:需兼顾叶子与容器的不同需求。
  • 可能违反接口隔离原则:需要为不需要的方法提供空实现。

3、应用场景

  • GUI组件库(窗口包含面板/按钮等)。
  • 组织架构管理系统(部门包含员工/子部门)。
  • 数学表达式解析(操作符包含子表达式)。
  • 游戏场景图(父节点包含子节点)。
  • XML/JSON文档处理。

当系统需要处理树形结构,且希望以统一方式操作层次中的不同元素时,组合模式是最佳选择。其价值在于模糊了简单元素与复杂元素的边界,让复杂的层次结构变得易于管理和扩展。

相关推荐
下地种菜小叶2 分钟前
接口幂等怎么设计?一次讲清重复提交、支付回调、幂等键与防重落地方案
java·spring boot·spring·kafka·maven
YDS8292 分钟前
大营销平台 —— 模板方法串联前中置抽奖规则
java·spring boot·ddd
.柒宇.3 分钟前
Java八股之== 与 equals 区别
java·开发语言
时间静止不是简史3 分钟前
当MyBatis-Plus的like遇上SQL通配符:下划线翻车记
java·sql·mybatis
两年半的个人练习生^_^7 分钟前
每日一学:设计模式之建造者模式
java·开发语言·设计模式
我登哥MVP8 分钟前
【SpringMVC笔记】 - 6 - RESTFul编程风格
java·spring boot·spring·servlet·tomcat·maven·restful
yhole12 分钟前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
zjjsctcdl13 分钟前
SpringBoot3.3.0集成Knife4j4.5.0实战
java
彭于晏Yan14 分钟前
Spring Boot 集成邮件服务实现发送邮件功能
java·spring boot·后端
浮尘笔记15 分钟前
Java Snowy 框架生产环境安全部署全流程(服务器篇)
java·运维·服务器·开发语言·后端