组合模式

结构型模式

访问次数: 12

组合模式将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

类图
classDiagram
    class Component {
        <<interface>>
        +operation()
        +add(component: Component)
        +remove(component: Component)
        +getChild(index: int) Component
    }
    class Leaf {
        +operation()
    }
    class Composite {
        -children: List~Component~
        +operation()
        +add(component: Component)
        +remove(component: Component)
        +getChild(index: int) Component
    }
    Component <|-- Leaf
    Component <|-- Composite
    Composite --> Component : contains
源代码示例
// 抽象组件
interface Component {
    void operation();
    void add(Component component);
    void remove(Component component);
    Component getChild(int index);
}

// 叶子节点
class Leaf implements Component {
    private String name;
    
    public Leaf(String name) {
        this.name = name;
    }
    
    @Override
    public void operation() {
        System.out.println("Leaf " + name + " operation");
    }
    
    @Override
    public void add(Component component) {
        throw new UnsupportedOperationException("Cannot add to leaf");
    }
    
    @Override
    public void remove(Component component) {
        throw new UnsupportedOperationException("Cannot remove from leaf");
    }
    
    @Override
    public Component getChild(int index) {
        throw new UnsupportedOperationException("Leaf has no children");
    }
}

// 组合节点
class Composite implements Component {
    private String name;
    private List<Component> children = new ArrayList<>();
    
    public Composite(String name) {
        this.name = name;
    }
    
    @Override
    public void operation() {
        System.out.println("Composite " + name + " operation");
        for (Component child : children) {
            child.operation();
        }
    }
    
    @Override
    public void add(Component component) {
        children.add(component);
    }
    
    @Override
    public void remove(Component component) {
        children.remove(component);
    }
    
    @Override
    public Component getChild(int index) {
        return children.get(index);
    }
}
# Python代码待添加
应用场景
当需要表示树形结构,且希望对叶子节点和组合节点进行统一处理时。应用场景包括: 1)文件系统中的文件和文件夹,可以对文件和文件夹执行统一的操作(复制、删除、移动) 2)图形界面中的容器和控件,容器可以包含其他容器或控件,形成嵌套的UI结构 3)组织结构管理,公司、部门、员工形成树形结构,可以统一处理组织关系 4)菜单系统,菜单项可以是叶子节点(具体功能)或组合节点(子菜单) 5)XML/HTML文档结构,元素可以包含文本节点或其他元素节点 6)游戏场景图,场景可以包含子场景、游戏对象、特效等不同类型的节点
精选场景详解 —— 文件系统:统一处理文件与文件夹
问题背景

复制/删除/统计大小时,若对 File 和 Folder 写两套逻辑,客户端要不断判断类型;文件夹又可嵌套文件夹,结构是递归树。

模式如何解决
选用组合模式:FileSystemNode 作为统一组件接口;File 是叶子,Folder 是容器并持有子节点列表。客户端对根节点调用 display/delete/getSize,无需区分叶子与容器。 结构上形成树:Folder → (File | Folder)*。 适用特征:部分-整体层次、希望「透明地」对单个对象与组合对象使用同一操作。UI 控件树、组织架构、菜单树同理。
场景模型(角色映射)

将模式中的抽象角色映射到该业务领域的具体类:

classDiagram
    class FileSystemNode {
        <<interface>>
        +getName() String
        +getSize() long
        +display(indent: int)
        +delete()
    }
    class FileNode {
        -size: long
        +getSize() long
        +display(indent: int)
        +delete()
    }
    class FolderNode {
        -children: List~FileSystemNode~
        +add(node: FileSystemNode)
        +remove(node: FileSystemNode)
        +getSize() long
        +display(indent: int)
        +delete()
    }
    class FileManager {
        +copy(src: FileSystemNode, dest: FolderNode)
    }
    FileSystemNode <|.. FileNode
    FileSystemNode <|.. FolderNode
    FolderNode --> FileSystemNode : contains
    FileManager --> FileSystemNode