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

结构

  • 组件接口(Component): 声明了叶子和容器对象的共同接口,客户端通过该接口操作组合结构中的对象。
public interface Component {
    void operation();
}
  • 叶子类(Leaf): 实现了组件接口,表示组合中的叶子对象,叶子对象没有子节点。
public class Leaf implements Component {
    public void operation() {
        System.out.println("Leaf operation");
    }
}
  • 容器类(Composite): 实现了组件接口,表示组合中的容器对象,可以包含子节点(既可以是叶子对象,也可以是其他容器对象)。
import java.util.ArrayList;
import java.util.List;

public class Composite implements Component {
    private List<Component> children = new ArrayList<>();

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

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

    public void operation() {
        System.out.println("Composite operation");
        for (Component component : children) {
            component.operation();
        }
    }
}

优点和缺点

优点:

  1. 统一接口: 组合模式统一了单个对象和组合对象的接口,使得客户端可以一致地处理它们。
  2. 灵活性: 客户端可以像处理单个对象一样,处理组合对象,从而使得系统更加灵活。
  3. 递归结构: 组合模式构建了递归结构,使得客户端可以通过统一的方式遍历所有的叶子对象和容器对象。

缺点:

  1. 不易限制组件类型: 组合模式将叶子对象和容器对象都看作组件对象,难以限制容器对象只能包含特定类型的子节点。

示例

以下是一个组合模式的示例,表示一个文件系统的目录结构,其中文件和文件夹都是组件,文件夹可以包含其他文件和文件夹。

// 组件接口
public interface Component {
    void operation();
}

// 叶子类
public class File implements Component {
    private String name;

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

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

// 容器类
import java.util.ArrayList;
import java.util.List;

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

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

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

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

    public void operation() {
        System.out.println("Folder: " + name);
        for (Component component : children) {
            component.operation();
        }
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Component file1 = new File("file1.txt");
        Component file2 = new File("file2.txt");
        Component folder1 = new Folder("Folder 1");
        Component folder2 = new Folder("Folder 2");

        folder1.add(file1);
        folder1.add(file2);
        folder2.add(folder1);

        folder2.operation();
    }
}

在这个例子中,File 是叶子类,表示文件对象,Folder 是容器类,表示文件夹对象。客户端可以创建文件和文件夹,将文件添加到文件夹中,然后通过统一的接口调用它们的 operation 方法,实现对整个文件系统的操作。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注