从零开始学设计模式(十一):组合模式(Composite Pattern):

简介: 组合模式(Composite Pattern)又叫做部分-整体模式,它在树型结构(可以想象一下数据结构中的树)的问题中,模糊了简单元素和复杂元素的概念,客户端程序可以像处理简单元素一样来处理复杂元素,而使得客户端程序与复杂元素的内部结构进行解藕。

定义:


组合模式(Composite Pattern)又叫做部分-整体模式,它在树型结构(可以想象一下数据结构中的树)的问题中,模糊了简单元素和复杂元素的概念,客户端程序可以像处理简单元素一样来处理复杂元素,而使得客户端程序与复杂元素的内部结构进行解藕。


组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点。


如下图的工程目录结构就是一个树型结构:


d113abd5b9ca4529b459117631381872~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


它可以表示为下面的树型结构图:


e936205fd1624040b61b534f166ac365~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


由上面的结构图可以发现,根节点和树枝节点其实在本质上属于同一种数据类型,它们都可以作为容器使用;但是叶子节点与树枝节点其实在语义上是不属于同一种类型。但是在组合模式中,是把树枝节点和叶子节点看作属于同一种数据类型(这里是用统一接口定义),从而使得让它们具备一致行为。


所以在组合模式中,整个的树形结构中的对象就会都属于同一种类型,这样的好处就是不需要用户来辨别是树枝节点还是叶子节点,就可以直接进行操作,给用户的使用带来极大的便利。


组成部分:


通过上述对于组合模式的描述,可以总结出组合模式的几个组成部分:


1、Component: 组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件,不管是组合还是叶结点。


2、Leaf: 在组合中表示叶子结点对象,叶子结点没有子结点。


3、Composite: 容器对象,表示参加组合的有子对象的对象,定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加和删除等。


栗子


用上面文件夹的例子,首先声明一个文件夹相关的Component,FolderComponent:


public abstract class FolderComponent {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(final String name) {
        this.name = name;
    }
    public FolderComponent() {
    }
    public FolderComponent(final String name) {
        this.name = name;
    }
    public abstract void add(FolderComponent component);
    public abstract void remove(FolderComponent component);
    public abstract void display();
}
复制代码


再声明一个叶子节点文件夹,定义为FileLeaf,并且继承上面的FolderComponent:


public class FileLeaf  extends FolderComponent{
    public FileLeaf(final String name) {
        super(name);
    }
    @Override
    public void add(FolderComponent component) {
    }
    @Override
    public void remove(FolderComponent component) {
    }
    @Override
    public void display() {
        System.out.println("叶子文件:" + this.getName());
    }
}
复制代码


最后声明一个容器对象,FolderComposit


public class FolderComposite extends FolderComponent {
    private final List<FolderComponent> components;
    public FolderComposite(final String name) {
        super(name);
        this.components = new ArrayList<FolderComponent>();
    }
    public FolderComposite() {
        this.components = new ArrayList<FolderComponent>();
    }
    @Override
    public void add(final FolderComponent component) {
        this.components.add(component);
    }
    @Override
    public void remove(final FolderComponent component) {
        this.components.remove(component);
    }
    @Override
    public void display() {
        System.out.println("文件夹组合容器的名字是" + this.getName());
        for (final FolderComponent component : components) {
            System.out.println("文件夹组合容器的当前文件夹是" + component.getName());
        }
    }
}
复制代码


测试方法:


public class CompositePatternTest {
    public static void main(final String[] args)    {
        final FolderComponent leaf = new FileLeaf("叶子文件");
        leaf.display();
        final FolderComponent folder = new FolderComposite("文件夹一");
        folder.add(new FileLeaf("文件夹里面的文件二"));
        folder.add(new FileLeaf("文件夹里面的文件三"));
        folder.display();
    }
}
复制代码


运行结果如下:


f4b4accf53a9434596b0571bc71df0f0~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


通过上面的例子可以总结出组合模式的优点和缺点。


组合模式的优点


1、组合模式使得客户端代码可以一致地处理单个对象和组合对象,从而无须关心自己处理的是单个对象,还是组合对象,大大地简化了代码结构;


2、组合模式的使用使得更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,实现了设计模式原则的“开闭原则”;


组合模式的缺点


1、使用组合模式需要花较多地时间理清类之间的层次关系,所以设计较复杂;


2、组合模式理解和设计较为复杂,增加代码难度;


3、如果使用了组合模式就不容易限制容器中的构件;


4、组合模式中不容易用继承的方法来增加构件的新功能;


使用场景


组合模式适用于以下情况:


1、当想要表示对象的部分-整体层次结构


2、当想要用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。


总结


使用组合模式方便解耦客户端与复杂元素的内部结构,从而使得客户端程序可以像处理简单元素一样来一致处理复杂元素,大大简化了代码。对于层次结构的系统对象,可以使用组合模式进行处理。

目录
相关文章
|
4月前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 组合模式
js设计模式【详解】—— 组合模式
52 7
|
2月前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
2月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
2月前
|
设计模式 存储 安全
Java设计模式-组合模式(13)
Java设计模式-组合模式(13)
|
2月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
4月前
|
设计模式
对抗软件复杂度问题之组合(Composite)方法设计模式是什么,如何解决
对抗软件复杂度问题之组合(Composite)方法设计模式是什么,如何解决
|
5月前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)
|
5月前
|
设计模式 存储 安全
Java设计模式:组合模式之透明与安全的两种实现(七)
Java设计模式:组合模式之透明与安全的两种实现(七)
|
5月前
|
设计模式 Java
Java设计模式之组合模式详解
Java设计模式之组合模式详解
|
5月前
|
设计模式
组合模式-大话设计模式
组合模式-大话设计模式

热门文章

最新文章

  • 1
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    45
  • 2
    C++一分钟之-C++中的设计模式:单例模式
    51
  • 3
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    36
  • 4
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    59
  • 5
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    54
  • 6
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    39
  • 7
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 8
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    102
  • 9
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    74
  • 10
    Go语言设计模式:使用Option模式简化类的初始化
    71