Java 设计模式-组合模式

发布于:2025-08-15 ⋅ 阅读:(12) ⋅ 点赞:(0)

Java 设计模式-组合模式

模式概述

组合模式简介

定义:组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端可以统一处理单个对象和对象组合。

模式类型:结构型模式

作用

  • 提供了一种统一的方式来访问树状结构中的各个节点。
  • 客户端代码不需要区分简单元素和复杂组合,能够以一致的方式处理它们。

典型应用场景

  • GUI控件嵌套结构(如窗口、面板等)
  • 文件和目录系统

我认为:通过使用组合模式,我们可以创建一个递归的对象结构,简化了客户端代码对复杂层次结构的操作。

课程目标

  • 理解组合模式的核心思想和经典应用场景
  • 识别应用场景,使用组合模式解决功能要求
  • 了解组合模式的优缺点

核心组件

角色-职责表

角色 职责 示例类名
Component 定义参与组合对象的接口 Component
Leaf 表示叶子节点,没有子节点 Leaf
Composite 表示复合组件,包含子组件 Composite

类图

透明组合模式类图:

«abstract»
Component
-name: String
+add(Component)
+remove(Component)
+operation()
Leaf
+operation()
Composite
-children: List
+operation()

安全组合模式类图:

«interface»
Component
+operation()
Leaf
-name: String
+operation()
Composite
-children: List
+add(Component)
+remove(Component)
+operation()

传统实现 VS 组合模式

案例需求

案例背景:构建一个简单的文件系统,其中包含文件和目录两种类型的节点。每个目录可以包含多个文件或其他目录。

传统实现(痛点版)

代码实现

// 传统写法代码片段
public class File {
    private String name;

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

    public void ls() {
        System.out.println(name);
    }
}

public class Directory {
    private String name;
    private List<File> files = new ArrayList<>();

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

    public void add(File file) {
        files.add(file);
    }

    public void ls() {
        System.out.println(name);
        for (File file : files) {
            file.ls();
        }
    }
}

痛点总结

  • 需要为每种类型的节点编写不同的代码,难以维护。
  • 不支持多级的文件系统实现。

组合模式 实现(优雅版)

代码实现

// 模式写法代码片段
public abstract class Component {
    protected String name;

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

    public abstract void ls();
}

public class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void ls() {
        System.out.println(name);
    }
}

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

    public Composite(String name) {
        super(name);
    }

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

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

    @Override
    public void ls() {
        System.out.println(name);
        for (Component component : children) {
            component.ls();
        }
    }
}

优势

  • 提供了一致的接口,方便扩展和维护。
  • 支持任意层次的嵌套结构。

局限

  • 可能会导致过度设计,在简单场景下显得冗余。

模式变体

  • 透明组合模式:所有组件提供相同的方法集,包括那些仅对复合组件有意义的方法。
  • 安全组合模式:只有在适当的地方才提供方法,避免不必要的操作。但必须区分叶子构件和容器构件,不能保持组件的一致性。

透明组合模式优于安全组合模式,虽然在叶子构件中用add()或remove()会报错,但保持了组件一致性,便于进行抽象编程。


最佳实践

建议 理由
尽量保持组件的一致性(透明组合模式) 有助于简化客户端代码
考虑使用迭代器或访问者模式增强遍历能力 提高灵活性和复用性

一句话总结

组合模式使我们能够以一致的方式处理简单和复杂的对象组合,简化了树状结构的管理。

如果关注Java设计模式内容,可以查阅作者的其他Java设计模式系列文章。😊


网站公告

今日签到

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