组合模式

一、模式概述(What & When)

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

适用场景:

  • 需要表示对象的部分-整体层次结构
  • 希望用户忽略组合对象与单个对象的不同,统一处理所有对象
  • 处理树形结构数据,如文件系统、公司组织架构等

二、模式角色说明(Who)

主要角色:

  1. Component(抽象构件):定义参与组合的对象的共同接口
  2. Leaf(叶子节点):表示叶子对象,没有子节点
  3. Composite(树枝节点):存储子部件,实现Component接口相关操作

基本实现:

public abstract class Component {
    protected String name;
    
    public Component(String name) {
        this.name = name;
    }
    
    public abstract void add(Component c);
    public abstract void remove(Component c);
    public abstract void display(int depth);
}

public class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }
    
    @Override
    public void add(Component c) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void remove(Component c) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
    }
}

public class Composite extends Component {
    private List<Component> children = new ArrayList<>();
    
    public Composite(String name) {
        super(name);
    }
    
    @Override
    public void add(Component c) {
        children.add(c);
    }
    
    @Override
    public void remove(Component c) {
        children.remove(c);
    }
    
    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
        for (Component component : children) {
            component.display(depth + 2);
        }
    }
}

三、角色类比(生活类比帮助理解)

设计模式角色类比对象类比说明
Component组织成员定义所有成员的共同特征和行为
Composite部门经理可以管理其他成员,自身也是成员
Leaf普通员工最基本单元,无下属

四、实际应用场景(Where)

  1. Java AWT/Swing GUI组件体系
    • Container和Component构成组合模式
    • Container可以包含其他Component,形成树形结构
    • 统一处理用户事件和绘制逻辑
public class Container extends Component {
     private List<Component> components = new ArrayList<>();
     
     public Component add(Component comp) {
          components.add(comp);
          return comp;
     }
}
  1. Spring Security过滤器链
    • CompositeFilter实现组合模式
    • 可以组合多个SecurityFilter
    • 提供统一的请求过滤机制
public class CompositeFilter implements Filter {
     private List<Filter> filters = new ArrayList<>();
     
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
          new VirtualFilterChain(chain, filters).doFilter(request, response);
     }
}
  1. Spring Boot配置属性处理
    • ConfigurationPropertySource接口
    • CompositePropertySource可组合多个属性源
    • 统一配置属性的获取方式
public class CompositePropertySource extends PropertySource<Object> {
     private final Set<PropertySource<?>> propertySources = new LinkedHashSet<>();
     
     public void addPropertySource(PropertySource<?> propertySource) {
          this.propertySources.add(propertySource);
     }
}

实现要点:

  • 利用接口定义统一行为
  • 使用集合存储子组件
  • 递归处理组合对象
  • 维护父子关系(可选)
  • 注意异常处理机制

五、列举现实系统可应用的场景

  1. 文件系统目录结构
  2. 公司组织架构管理
  3. 菜单系统(主菜单-子菜单)
  4. 电商系统的商品分类
  5. IDE的项目文件结构
  6. 网页DOM树结构
  7. 图形绘制系统(复合图形)
  8. 游戏场景的对象树
  9. 任务系统的子任务分解
  10. 权限系统的功能模块划分

六、总结与实践建议(Why)

优点:

  • 简化客户端代码,统一处理复杂和简单对象
  • 易于增加新类型的组件
  • 符合开闭原则

缺点:

  • 很难限制组合中的组件类型
  • 使设计变得更加抽象

使用建议:

  1. 确保树形结构确实需要统一处理
  2. 注意组件接口的设计,不要过度抽象
  3. 考虑是否需要父节点引用
  4. 在遍历时注意性能问题
  5. 避免在叶子节点中实现无意义的组合操作

不推荐使用场景:

  • 树形结构不明显的场景
  • 节点之间关系复杂,不是简单的包含关系
  • 需要频繁修改树形结构的场景

更多推荐