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

介绍

组合模式(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. 总结


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

相关推荐
小白不太白9506 小时前
设计模式之建造者模式
java·设计模式·建造者模式
菜菜-plus8 小时前
java 设计模式 模板方法模式
java·设计模式·模板方法模式
萨达大8 小时前
23种设计模式-模板方法(Template Method)设计模式
java·c++·设计模式·软考·模板方法模式·软件设计师·行为型设计模式
机器视觉知识推荐、就业指导10 小时前
C++设计模式:原型模式(Prototype)
c++·设计模式·原型模式
阳光开朗_大男孩儿10 小时前
组合模式和适配器模式的区别
设计模式·组合模式·适配器模式
MinBadGuy10 小时前
【GeekBand】C++设计模式笔记13_Flyweight_享元模式
c++·设计模式
Clang's Blog11 小时前
23种设计模式详解(以Java为例)
java·开发语言·设计模式
程序员奇奥12 小时前
设计模式——简单工厂模型、工厂模式、抽象工厂模式、单例模式、代理模式、模板模式
单例模式·设计模式·抽象工厂模式
hxj..12 小时前
【设计模式】代理模式
java·设计模式·代理模式·动态代理
十五年专注C++开发12 小时前
C++不完整类型(Incomplete Type)的检测与避免
开发语言·c++·算法·设计模式