组合模式 (Composite Pattern)

发布于:2024-11-27 ⋅ 阅读:(10) ⋅ 点赞:(0)

组合模式 (Composite Pattern)

组合模式是一种 结构型设计模式,它将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户端可以用统一的方式处理单个对象和组合对象。


原理

  1. 核心思想
    • 将对象的“部分”与“整体”组织成树形结构,以统一的方式操作单个对象和组合对象。
    • 客户端无需关心对象是简单的还是复杂的,它们都遵循相同的接口。
  2. 适用场景
    • 表示对象的 部分-整体 层次结构。
    • 希望客户端对单个对象和组合对象进行一致操作。
  3. 参与角色
    • Component(抽象构件):为组合中的对象声明接口。
    • Leaf(叶子节点):定义组合中的叶子对象。
    • Composite(容器构件):定义有子部件的对象,存储子部件并实现 Component 接口。

优点

  1. 一致性操作:客户端代码可以一致地操作简单对象和组合对象,无需关心具体类型。
  2. 灵活扩展:可以动态地增加和删除组合中的节点。
  3. 树形结构:非常适合用于表示复杂的层次结构。

缺点

  1. 复杂性增加:由于需要支持递归组合,代码可能变得复杂。
  2. 不易限制类型:在某些场景中,可能希望对子节点类型施加限制,但组合模式的设计使其较难实现。

示例代码

场景描述

设计一个文件系统,包含文件和文件夹,文件夹可以包含文件或子文件夹。用户可以查看文件系统的内容,统一显示文件和文件夹信息。


1. 定义抽象构件
// 抽象构件
public interface FileSystemComponent {
    void show(); // 显示组件信息
}

2. 创建叶子节点
// 叶子节点:文件
public class File implements FileSystemComponent {
    private String name;

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

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

3. 创建容器构件
// 容器节点:文件夹
import java.util.ArrayList;
import java.util.List;

public class Folder implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> children = new ArrayList<>();

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

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

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

    @Override
    public void show() {
        System.out.println("Folder: " + name);
        for (FileSystemComponent child : children) {
            child.show(); // 递归调用子节点的 show 方法
        }
    }
}

4. 客户端代码
public class CompositePatternExample {
    public static void main(String[] args) {
        // 创建文件
        File file1 = new File("file1.txt");
        File file2 = new File("file2.txt");
        File file3 = new File("file3.txt");

        // 创建文件夹
        Folder folder1 = new Folder("folder1");
        Folder folder2 = new Folder("folder2");
        Folder rootFolder = new Folder("root");

        // 组合文件和文件夹
        folder1.add(file1);
        folder1.add(file2);
        folder2.add(file3);
        rootFolder.add(folder1);
        rootFolder.add(folder2);

        // 显示文件系统结构
        rootFolder.show();
    }
}

输出结果
Folder: root
Folder: folder1
File: file1.txt
File: file2.txt
Folder: folder2
File: file3.txt

UML 类图

           +-----------------------+
           | FileSystemComponent   |
           +-----------------------+
           | + show()              |
           +-----------------------+
               ^              ^
               |              |
   +----------------+     +----------------+
   |      File       |     |     Folder     |
   +----------------+     +----------------+
   | + show()       |     | + add()        |
   |                |     | + remove()     |
   +----------------+     | + show()       |
                          +----------------+
                                |
                        +----------------+
                        | List<FileSystemComponent> |
                        +----------------+

使用场景

  1. 文件系统:文件和文件夹的树形表示。
  2. 组织结构:公司组织中部门和员工的层次结构。
  3. UI组件:如窗口、面板、按钮等组件的嵌套组合。

总结

  • 组合模式非常适合用于表示复杂的层次结构,并提供了一致的操作接口。
  • 它使得客户端代码能够轻松操作简单对象和组合对象,极大地提高了系统的灵活性。
  • 然而,在复杂场景中,设计和实现可能会变得困难,需要合理规划对象的组合关系。