设计模式-组合模式

发布于:2025-03-19 ⋅ 阅读:(90) ⋅ 点赞:(0)

组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次关系。它允许客户端以统一的方式处理单个对象和组合对象,无需关心具体是叶子节点还是容器节点。

核心思想

  • 统一接口:定义统一的抽象接口,让叶子对象和容器对象具有一致的行为。
  • 递归组合:容器对象可以包含其他容器或叶子对象,形成树状结构。
  • 透明性:客户端无需区分操作的是单个对象还是组合对象。

组合模式结构

组合模式包含三个关键角色:

  1. 组件(Component)
    定义:所有对象的通用接口(抽象类或接口)。
    职责:声明管理子组件的方法(如 add()、remove()),以及业务方法(如 operation())。

    public abstract class Component {
        // 管理子组件的方法(默认抛出异常,叶子节点无需实现)
        public void add(Component component) {
            throw new UnsupportedOperationException();
        }
        
        public void remove(Component component) {
            throw new UnsupportedOperationException();
        }
        
        public List<Component> getChildren() {
            throw new UnsupportedOperationException();
        }
        
        // 业务方法(由子类实现)
        public abstract void operation();
    }
    
  2. 叶子节点(Leaf)
    定义:树形结构中的基础元素,没有子节点。
    职责:实现组件的业务方法,不实现子组件管理方法。

    public class Leaf extends Component {
        @Override
        public void operation() {
            System.out.println("执行叶子节点操作");
        }
    }
    
  3. 容器节点(Composite)
    定义:包含子组件(可以是叶子或其他容器)的复杂元素。
    职责:实现子组件管理方法,并递归调用子组件的业务方法。

    public class Composite extends Component {
        private List<Component> children = new ArrayList<>();
    
        @Override
        public void add(Component component) {
            children.add(component);
        }
    
        @Override
        public void remove(Component component) {
            children.remove(component);
        }
    
        @Override
        public List<Component> getChildren() {
            return children;
        }
    
        @Override
        public void operation() {
            System.out.println("执行容器节点操作");
            // 递归调用子组件的 operation()
            for (Component child : children) {
                child.operation();
            }
        }
    }
    

优缺点分析

优点

  • 简化客户端代码:统一处理单个对象和组合对象。
  • 开闭原则:易于添加新类型的组件。
  • 灵活结构:支持动态构建复杂树形结构。

缺点

  • 设计抽象:需合理设计组件接口,过度通用化可能增加复杂度。
  • 类型检查:透明模式中需处理叶子节点不支持的方法调用。

代码示例:文件系统

假设需要表示一个文件系统中的文件和文件夹:

// 组件抽象类
public abstract class FileSystemComponent {
    protected String name;
    
    public FileSystemComponent(String name) {
        this.name = name;
    }
    
    public void add(FileSystemComponent component) {
        throw new UnsupportedOperationException();
    }
    
    public void remove(FileSystemComponent component) {
        throw new UnsupportedOperationException();
    }
    
    public abstract void display();
}

// 叶子节点:文件
public class File extends FileSystemComponent {
    public File(String name) {
        super(name);
    }
    
    @Override
    public void display() {
        System.out.println("文件:" + name);
    }
}

// 容器节点:文件夹
public class Directory extends FileSystemComponent {
    private List<FileSystemComponent> children = new ArrayList<>();
    
    public Directory(String name) {
        super(name);
    }
    
    @Override
    public void add(FileSystemComponent component) {
        children.add(component);
    }
    
    @Override
    public void remove(FileSystemComponent component) {
        children.remove(component);
    }
    
    @Override
    public void display() {
        System.out.println("文件夹:" + name);
        for (FileSystemComponent child : children) {
            child.display();
        }
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        FileSystemComponent root = new Directory("根目录");
        
        FileSystemComponent file1 = new File("文档.txt");
        FileSystemComponent file2 = new File("图片.jpg");
        
        Directory subDir = new Directory("子文件夹");
        subDir.add(new File("代码.java"));
        
        root.add(file1);
        root.add(file2);
        root.add(subDir);
        
        root.display();
    }
}

// 输出:
// 文件夹:根目录
// 文件:文档.txt
// 文件:图片.jpg
// 文件夹:子文件夹
// 文件:代码.java

应用场景

适用场景

  • 表示树形结构(如文件系统、组织架构、UI组件嵌套)。
  • 希望客户端以统一方式处理简单元素和复杂元素。
  • 需要动态添加或移除层次结构中的对象。

实际应用

  • Java Swing:JComponent 作为组件,Container 作为容器。
  • XML解析:DOM树中的元素和子元素。
  • 企业组织架构:部门与员工的层级管理。

与其他模式的关系

  • 与装饰器模式:组合模式关注结构组合,装饰器模式关注动态添加职责。
  • 与迭代器模式:常结合使用,遍历组合结构中的元素。
  • 与访问者模式:通过访问者统一处理不同节点类型。

总结

组合模式通过树形结构和统一接口,实现了部分-整体关系的优雅管理。在需要处理层次化数据的场景中(如UI组件、文件系统),它能显著提升代码的可维护性和扩展性。


网站公告

今日签到

点亮在社区的每一天
去签到