技术成神之路:设计模式(十七)组合模式

介绍

组合模式(Composite Pattern)是一种结构型设计模式,它使你能够将对象组合成树形结构来表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

1.定义


组合模式允许将叶子对象和组合对象(容器对象)统一处理。

2. 主要作用


  • 简化客户端代码:客户端可以使用相同的方式处理单个对象和组合对象,减少了代码复杂度。
  • 构建树形结构:能够轻松地创建和管理复杂的树形结构。
  • 便于扩展:新增的叶子对象或组合对象不需要修改现有代码。

3. 解决的问题


  • 在需要处理树形结构时,直接使用传统的对象管理会导致复杂性和不一致性。
  • 组合模式提供了一种方式,使得叶子节点和组合节点都实现相同的接口,从而提供了一种一致的调用方式。

4. 模式原理


包含角色:

  • Component(组件):定义了组合对象和叶子对象的共同接口,可以包含一些默认的行为。
  • Leaf(叶子节点):叶子节点,只实现了Component接口的行为,不包含其他子节点。
  • Composite(组合节点):组合节点,实现了Component接口,并且包含子节点的管理功能,比如添加、删除和遍历子节点。

UML类图:

简单示例:

java 复制代码
// Component
interface FileSystemComponent {
    void showDetails();
}

// Leaf
class File implements FileSystemComponent {
    private String name;

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

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

// Composite
class Folder implements FileSystemComponent {
    private String name;
    private List<FileSystemComponent> components = new ArrayList<>();

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

    public void addComponent(FileSystemComponent component) {
        components.add(component);
    }

    public void removeComponent(FileSystemComponent component) {
        components.remove(component);
    }

    @Override
    public void showDetails() {
        System.out.println("Folder: " + name);
        for (FileSystemComponent component : components) {
            component.showDetails();
        }
    }
}

调用

java 复制代码
public class CompositePatternDemo {
    public static void main(String[] args) {
        FileSystemComponent file1 = new File("File1.txt");
        FileSystemComponent file2 = new File("File2.txt");

        Folder folder = new Folder("MyFolder");
        folder.addComponent(file1);
        folder.addComponent(file2);

        folder.showDetails();
    }
}

打印输出

复制代码
Folder: MyFolder
File: File1.txt
File: File2.txt

到这里,不知道你是不是有和我同样的疑问,在Java中 File 是不是实现了组合模式?

File类中,文件和目录(文件夹)之间的关系可以被看作是组合模式的体现。一个File对象可以表示一个文件,也可以表示一个目录。目录可以包含多个File对象(文件和子目录),形成树状结构,而且他们都有统一的方法 listFiles()delete()renameTo()等。这意味着,无论你在操作文件还是目录,都可以通过相同的方法来进行操作,这体现了组合模式的核心思想。BUTFile 类本身并没有直接实现组合模式,可以被视为一种组合模式的应用,并非严格意义上的组合模式。

类似的还有 Java 的集合框架中,java.util.Listjava.util.Set 等接口的实现类如 ArrayListHashSet等。

那么,在SDK中有没有典型的组合模式实例?答案是肯定的。

在 Android 中,View 是所有 UI 组件的基类,而 ViewGroup 是一个特殊的 View,它可以包含其他 View

Component(组件)View 是基本组件,代表 UI 中的一个元素。
Leaf(叶子节点)View 又代表叶子节点,因为它们不包含子视图。
Composite(组合节点)ViewGroup 代表组合节点,可以包含多个 View 或其他 ViewGroup

这样就可以统一创建和管理复杂的用户界面了。

5. 优缺点


优点:

  1. 客户端可以以一致的方式处理单个对象和组合对象。
  2. 增加新组件时,系统的扩展性良好。

缺点:

  1. 设计复杂性增加,因为需要定义一个接口或抽象类。
  2. 不适合过于复杂的树形结构。

6. 应用场景


  • 想表示对象的部分-整体层次结构。
  • 希望用户忽略组合对象和单个对象的不同,用户将统一地使用组合结构中的所有对象。

7. 总结


组合模式是一种强大的设计模式,适用于处理树形结构中的对象关系。通过将对象组合成树形结构,组合模式使得客户端可以统一地处理单个对象和组合对象,从而简化了代码逻辑和结构。然而,组合模式也增加了类的复杂性,需要在设计时权衡其优缺点。

相关推荐
AI人工智能+电脑小能手3 小时前
大白话说Java设计模式-08-建造者模式(业务实战篇)
java·设计模式·建造者模式·架构设计·对象构建
AustinXu6 小时前
从 Claude Code 到 Claude Tag,Harness Engineering 走到了组织这一层
设计模式·团队管理
剧中有戏6 小时前
单例模式从入门到精通:一个数据库连接池的完整剖析
设计模式
胡萝卜术6 小时前
编译期与运行期的双重防线:从 TypeScript 类型之争到 LLM 输出的自动化择优
前端·设计模式·面试
货拉拉技术7 小时前
重塑 Agent 度量衡:基于 LLM-as-a-Judge 的离线评估体系与实践
算法·设计模式
KhalilRuan7 小时前
设计模式小记
设计模式
卡牌RWA研究院7 小时前
Relique:一张精品卡牌如何从收藏品变成可交易的链上资产?
设计模式·金融·区块链·创业创新
剧中有戏1 天前
抽象工厂模式从入门到精通:一个多云存储案例的完整剖析(修订版)
设计模式
MC皮蛋侠客1 天前
Redis 系列(八):缓存设计模式与一致性——从 Cache Aside 到防雪崩
redis·缓存·设计模式
莫得感情 o1 天前
设计模式 18 · 状态模式
设计模式·状态模式