设计模式笔记_结构型_组合模式

1. 组合模式介绍

组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示"整体/部分"层次结构。组合模式使得用户可以对单个对象和组合对象进行一致的处理。

类比:想象一下文件系统中的目录和文件。一个目录可以包含多个文件,也可以包含其他目录。无论是文件还是目录,你都可以执行诸如打开、关闭等操作。组合模式就是这样一种设计,它使得你可以用统一的方式处理文件和目录。

优点

  1. 简化客户端代码:客户端代码可以一致地处理单个对象和组合对象,无需关心它们的具体类型。
  2. 易于扩展:可以轻松地增加新的组件类型,只需确保它们符合组合接口。
  3. 结构灵活:可以方便地创建复杂的递归结构,比如树形结构。

2. 代码演示

使用组合模式来模拟文件系统中的目录和文件。通过组合模式,我们可以将文件和目录统一处理,因为目录可以包含文件和其他子目录。

组件接口:

java 复制代码
// 组件接口
public interface FileSystemComponent {
    //定义通用的showDetails()方法,用于展示组件的详细信息。
    void showDetails();
}

叶子节点 - 文件:

java 复制代码
// File类实现了FileSystemComponent接口,代表文件
public class File implements FileSystemComponent {
    private String name;

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

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

组合节点 - 目录:

java 复制代码
// Directory类也实现了FileSystemComponent接口,代表目录。
// 目录可以包含多个FileSystemComponent,即可以包含文件和其他子目录。
public class Directory implements FileSystemComponent {
    private List<FileSystemComponent> components = new ArrayList<>();
    private String name;

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

    public void addComponent(FileSystemComponent component) {
        components.add(component);
    }

    public void removeComponent(FileSystemComponent component) {
        components.remove(component);
    }

    @Override
    public void showDetails() {
        System.out.println("Directory: " + name);
        //多层目录结构,可递归处理
        for (FileSystemComponent component : components) {
            component.showDetails();
        }
    }
}

**使用组合模式的客户端代码:**以相同的方式处理单个对象(File)和组合对象(Directory),无需关心它们的具体类型:

java 复制代码
// 使用组合模式的客户端代码
public class FileSystemDemo {
    public static void main(String[] args) {
        // 创建文件
        File file1 = new File("file1.txt");
        File file2 = new File("file2.txt");

        // 创建目录1并添加文件
        Directory dir1 = new Directory("dir1");
        dir1.addComponent(file1);

        Directory dir2 = new Directory("dir2");
        dir2.addComponent(file2);
        dir2.addComponent(dir1); // 将dir1作为子目录添加到dir2

        // 显示目录结构: 文件和目录可以以统一的方式进行处理
        dir2.showDetails();
    }
}

对应的类图如下: