23种设计模式——组合模式(Composite Pattern)

✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。
🍎个人主页:Meteors.的博客
💞当前专栏:设计模式
✨特色专栏:知识分享
🥭本文内容:23种设计模式------组合模式(Composite Pattern)
📚 ** ps ** :阅读文章如果有问题或者疑惑,欢迎在评论区提问或指出。


目录

[一. 背景](#一. 背景)

[二. 介绍](#二. 介绍)

[三. 核心概念](#三. 核心概念)

[四. 代码示例](#四. 代码示例)

[五. 特点](#五. 特点)

[六. 适用场景](#六. 适用场景)

[七. 最佳实践](#七. 最佳实践)

[八. 总结](#八. 总结)


一. 背景

组合,想必学过设计模式或者UML的都不陌生,不就一个类引用另一个类作为实例吗。但是加上模式二字,可能很多人就不知道了...但是我提醒你,存有许多文件的文件夹就是这种模式的标准案例,你的脑海中,就有一个大概的模型了。


二. 介绍

组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示"部分-整体"的层次关系。这种模式使得客户端可以统一地处理单个对象和对象组合,而不需要区分它们是叶子节点还是组合节点。


三. 核心概念

组件接口(Component): 定义树中对象的共同接口,可以是抽象类或接口
叶子节点(Leaf): 树中的终端节点,不包含子节点
**复合节点(Composite):**包含子节点的节点,实现组件接口并管理子节点


四. 代码示例

下面是一个使用了组合模式的文件夹demo:

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

// 1. 组件接口 (Component)
abstract class FileSystemComponent {
    protected String name;
    
    public FileSystemComponent(String name) {
        this.name = name;
    }
    
    public abstract void display(int depth);
    public abstract long getSize();
}

// 2. 叶子节点 (Leaf)
class File extends FileSystemComponent {
    private long size;
    
    public File(String name, long size) {
        super(name);
        this.size = size;
    }
    
    @Override
    public void display(int depth) {
        System.out.println(" ".repeat(depth) + "- File: " + name + " (" + size + "KB)");
    }
    
    @Override
    public long getSize() {
        return size;
    }
}

// 3. 复合节点 (Composite)
class Directory extends FileSystemComponent {
    private List<FileSystemComponent> children = new ArrayList<>();
    
    public Directory(String name) {
        super(name);
    }
    
    public void add(FileSystemComponent component) {
        children.add(component);
    }
    
    public void remove(FileSystemComponent component) {
        children.remove(component);
    }
    
    @Override
    public void display(int depth) {
        System.out.println(" ".repeat(depth) + "+ Directory: " + name);
        for (FileSystemComponent component : children) {
            component.display(depth + 2);
        }
    }
    
    @Override
    public long getSize() {
        long totalSize = 0;
        for (FileSystemComponent component : children) {
            totalSize += component.getSize();
        }
        return totalSize;
    }
}

// 使用示例
public class CompositePatternDemo {
    public static void main(String[] args) {
        // 创建文件
        File file1 = new File("file1.txt", 100);
        File file2 = new File("file2.jpg", 250);
        File file3 = new File("file3.pdf", 50);
        
        // 创建目录
        Directory root = new Directory("Root");
        Directory documents = new Directory("Documents");
        Directory images = new Directory("Images");
        
        // 构建树形结构
        root.add(documents);
        root.add(images);
        
        documents.add(file1);
        documents.add(file3);
        images.add(file2);
        
        // 显示文件系统结构
        root.display(0);
        
        // 计算总大小
        System.out.println("\nTotal size: " + root.getSize() + "KB");
    }
}

五. 特点

优点:

  • 统一处理单个对象和组合对象
  • 容易扩展和增加新的组件类型
  • 简化客户端代码,使其不需要区分个体和组合
  • 符合开闭原则

缺点:

  • 设计复杂,需要清晰定义组件接口
  • 难以限制容器中的构件类型
  • 不易用继承的方法来增加新的行为

六. 适用场景

  1. 表示对象的部分-整体层次结构
    • 文件系统、菜单系统、组织架构
    • 需要以树形结构表示的对象模型
  2. 希望用户忽略组合对象与单个对象的不同
    1. 客户端可以统一使用组合结构和单个对象
    2. 不想让客户端关注处理的是单个对象还是组合对象
  3. 结构具有递归特性
    1. UI界面组件(如Android的View和ViewGroup)
    2. XML/HTML文档结构
    3. 语法分析树

七. 最佳实践

明确组件接口: 组件接口应该定义组合中所有对象的公共行为
合理处理异常: 在Component中为叶子节点不支持的操作提供默认实现
考虑性能: 对于大型树结构,避免深度递归操作
**类型安全:**可以通过泛型等方式增强类型安全性


八. 总结

组合模式是一种强大的设计模式,特别适合处理具有层次结构的对象。它通过将对象组织成树形结构,使得客户端可以统一处理个体对象和组合对象。在实际开发中,特别是在UI系统和树形数据结构处理中,组合模式得到了广泛应用。

当你需要表示对象的部分-整体层次结构,并希望用户忽略组合对象与单个对象的不同,可以考虑使用组合模式。这种模式能够简化客户端代码,提高系统的可扩展性和可维护性。


最后,

其它设计模式会陆续更新,希望文章对你有所帮助!

相关推荐
端庄的战斗机11 小时前
javascript 设计模式(文章很长,请自备瓜子,水果和眼药水)
开发语言·javascript·设计模式
饼干哥哥17 小时前
我开发了一个「吃掉」别人Skill来升级的饕餮.Skill,现在免费开源
人工智能·设计模式·开源
CaffeinePro18 小时前
什么是系统架构?架构师到底在做什么?
设计模式·架构
AI人工智能+电脑小能手20 小时前
【大白话说Java面试题 第156题】【06_Spring篇】第16题:Spring 用到了哪些设计模式?
java·spring·设计模式·代理模式·工厂模式
前端百草阁1 天前
JavaScript 设计模式(23 种)
开发语言·前端·javascript·设计模式
geovindu1 天前
java: Singleton Pattern
java·开发语言·后端·单例模式·设计模式·创建型模式
geovindu2 天前
python: Functional Options Pattern
开发语言·后端·python·设计模式·惯用法模式·函数式选项模式
Kel2 天前
Pregel 为什么会成为LangGraph编排的心脏
人工智能·设计模式·架构
会周易的程序员2 天前
microLog 后端开发指南
开发语言·c++·物联网·设计模式·日志·iot·aiot
geovindu2 天前
go: Functional Options Pattern
开发语言·后端·设计模式·golang·函数式选项模式’·惯用法模式