详解组合模式
引言
有一种情况,当一组对象具有“整体—部分”关系时,如果我们处理其中一个对象或对象组合(区别对待),就可能会出现牵一发而动全身的情况,造成代码复杂。这个时候,组合模式就是一种可以用一致的方式对待这个系统,让我们一起来看一下。
1.概念
组合模式(Composite Patterm):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“整体—部分”(Part—Whole)模式,它是一种对象结构型模式。
简单理解:整体—部分结构构建成树形结构,“部分”表示叶子结点,把叶子对象和容器对象中的方法(特殊的、公共的)都抽象出来形成抽象角色,然后针对抽象角色编程,即可实现“对象使用的一致性”这个核心思想。
2.模式结构

3.模式分析
Component:抽象构件,可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。核心代码如下:
abstract class component{public abstract void add(Component c);//增加成员public abstract void remove(Component c);//删除成员public abstract Component getChild(int i);//获取成员public abstract void operation();//业务方法}
Leaf:叶子构件,在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。核心代码如下:
class Leaf extends Component {public void add(Component c){//异常处理或错误提示}public void remove(Component c) {//异常处理或错误提示}public Component getChild(int i) {//异常处理或错误提示return null;}public void operation() {//叶子构件具体业务方法的实现}}
Composite:容器构件,在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。核心代码如下:
class Composite extends Component{private ArrayList<Component> children = new ArrayList<Component>();public void add(Component c) {list.add(c);}public void remove(Component c){list.remove(c);}public Component getChild(int i) {return (Component) list.get(i);}public void operation() {//容器构件具体业务方法的实现//递归调用成员构件的业务方法for (Object obj : children) {((Component) obj).operation();}}}
4.具体实例分析

FileSystemComponent:抽象构件接口,定义了文件系统的叶子构件(文件)和容器构件(文件夹)的增删改查等方法,具体实例代码如下:
//抽象构件类:文件系统public interface FileSystemComponent {public void add(FileSystemComponent c);//增加成员public void remove(FileSystemComponent c);//删除成员public FileSystemComponent getChild(int i);//获取成员public void displayInfo();//显示文件信息}
File:叶子构件,实现抽象构件FileSystemComponent接口,该类表示文件夹下的文件,具体实例代码如下:
//叶子构件public class File implements FileSystemComponent{private String name;public File(String name) {this.name = name;}public void add(FileSystemComponent c){System.out.println("叶子结点不支持此方法");}public void remove(FileSystemComponent c) {System.out.println("叶子结点不支持此方法");}public FileSystemComponent getChild(int i) {System.out.println("叶子结点不支持此方法");return null;}public void displayInfo() {System.out.println("File: " + name);}}
Directory:容器构件,实现抽象构件FileSystemComponent接口,该类表示文件夹容器,如果想要查询文件夹下的各级文件夹(各级容器构件)或者文件(叶子构件),就需要递归的遍历文件夹,具体实例代码如下:
//容器构件public class Directory implements FileSystemComponent{private String name;private List<FileSystemComponent> list;public Directory(String name) {this.name = name;list = new ArrayList<>();}public void add(FileSystemComponent c) {list.add(c);}public void remove(FileSystemComponent c) {list.remove(c);}public FileSystemComponent getChild(int i) {return (FileSystemComponent) list.get(i);}public void displayInfo() {System.out.println("Directory: " + name + "/");for(FileSystemComponent fileSystemComponent : list){fileSystemComponent.displayInfo();}}}
Client:客户端,依次创建文件夹和下面的文件,模拟文件系统。具体实例代码如下:
public class Client {public static void main(String[] args) {//创建文件File file1 = new File("Java.doc");File file2 = new File("数据结构.doc");//创建文件夹Directory directory = new Directory("学习资料");directory.add(file1);directory.add(file2);Directory rootDirectory = new Directory("D盘");rootDirectory.add(directory);//展示文件系统结构rootDirectory.displayInfo();}}
运行程序,得到的结果如下:

5.优缺点
主要优点如下:
(1)组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。
(2)客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。
(3)在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符合“开闭原则”。
(4)组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。
主要缺点如下:
(1)在增加新构件时很难对容器中的构件类型进行限制。有时候我们希望一个容器中只能有某些特定类型的对象,例如在某个文件夹中只能包含文本文件,使用组合模式时,不能依赖类型系统来施加这些约束,因为它们都来自于相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。
6.适用情况
(1)在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们。
(2)在一个使用面向对象语言开发的系统中需要处理一个树形结构。
(3)在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。
相关文章:
详解组合模式
引言 有一种情况,当一组对象具有“整体—部分”关系时,如果我们处理其中一个对象或对象组合(区别对待),就可能会出现牵一发而动全身的情况,造成代码复杂。这个时候,组合模式就是一种可以用一致的…...
【系统架构设计师论文】云上自动化运维及其应用
随着云计算技术的迅猛发展,企业对云资源的需求日益增长。为了应对这一挑战,云上自动化运维(CloudOps)应运而生,它结合了DevOps理念和技术,通过自动化工具和流程来提高云环境的管理效率和服务质量。本文将探讨云上自动化运维的主要衡量指标,并详细介绍一个实际项目中如何…...
交换排序----快速排序
快速排序 快速排序是一种高效的排序算法,它采用分治法策略,将数组分为较小和较大的两个子数组,然后递归排序两个子数组。 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序…...
ES 与 MySQL 在较大数据量下查询性能对比
在进行数据查询性能测试的过程中,我的同事幺加明对 ES(Elasticsearch)和 MySQL 进行了相对较大数据量的测试,并整理了相关结果。在得到其授权的情况下,我将此对比案例分享给大家,在此再次向幺加明表示感谢。…...
C# 新语法中的字符串内插$和{}符号用法详解
自C#6.0开始提供一个新的语法糖,即"$" 符号,配合“{}”使用,它的作用除了是对String.format的简化,还可设置其格式模板,实现了对字符串的拼接优化。 语法格式: $"string {变量表达式}” 语…...
Nacos源码学习-本地环境搭建
本文主要记录如何在本地搭建Nacos调试环境来进一步学习其源码,如果你也刚好刷到这篇文章,希望对你有所帮助。 1、本地环境准备 Maven: 3.5.4 Java: 1.8 开发工具:idea 版本控制工具: git 2、下载源码 官方仓库地址 :https://git…...
windows 好工具
Windows文件夹目录大小分析工具WizTree...
计算机运行时提示错误弹窗“由于找不到 quazip.dll,无法继续执行代码。”是什么原因?“quazip.dll文件缺失”要怎么解决?
计算机运行时错误解析:解决“quazip.dll缺失”问题指南 在软件开发和日常计算机使用中,我们经常会遇到各种运行时错误。今天,我们将深入探讨一个常见的错误提示:“由于找不到quazip.dll,无法继续执行代码。”这一弹窗…...
创造未来:The Sandbox 创作者训练营如何赋能全球创造者
创作者训练营让创造者有能力打造下一代数字体验。通过促进合作和提供尖端工具,The Sandbox 计划确保今天的元宇宙是由一个个创造者共同打造。 2024 年 5 月,The Sandbox 推出了「创作者训练营」系列,旨在重新定义数字创作。「创作者训练营」系…...
R语言对简·奥斯汀作品中人物对话的情感分析
项目背景 客户是一家文学研究机构,他们希望通过对简奥斯汀作品中人物对话的情感分析,深入了解作品中人物的情感变化和故事情节的发展。因此,他们委托你进行一项情感分析项目,利用“janeaustenr”包中的数据集来构建情感分析模型。…...
股指期货基差为正数,这是啥意思?
在股指期货的世界里,有个挺重要的概念叫“基差”。说白了,基差就是股指期货的价格和它对应的现货价格之间的差价。今天,咱们就来聊聊当这个基差为正数时,到底意味着啥。 基差是啥? 先复习一下,基差 股指…...
黑马程序员MybatisPlus/Docker相关内容
Day01 MP相关知识 1. mp配置类: 2.条件构造器: 具体的实现例子: ①QuerryWapper: ②LambdaQueryWrapper: 3.MP的自定义SQL 4.MP的Service层的实现 5.IService下的Lambda查询 原SQL语句的写法: Lambda 查询语句的…...
使用 Vue 和 Canvas-Confetti 实现烟花动画特效
在开发中,为用户提供具有视觉冲击力的反馈是一种提升用户体验的好方法。今天,我们将结合 Vue 框架、canvas-confetti 和 Lottie 动画,创建一个动态对话框动画,其中包含炫酷的烟花特效。 效果图: 效果简介 当用户触发…...
【银河麒麟操作系统真实案例分享】内存黑洞导致服务器卡死分析全过程
了解更多银河麒麟操作系统全新产品,请点击访问 麒麟软件产品专区:https://product.kylinos.cn 开发者专区:https://developer.kylinos.cn 文档中心:https://documentkylinos.cn 现象描述 机房显示器连接服务器后黑屏ÿ…...
如何加强游戏安全,防止定制外挂影响游戏公平性
在现如今的游戏环境中,外挂始终是一个困扰玩家和开发者的问题。尤其是定制挂(Customized Cheats),它不仅复杂且隐蔽,更能针对性地绕过传统的反作弊系统,对游戏安全带来极大威胁。定制挂通常是根据玩家的需求…...
SpringBoot整合knife4j,以及会遇到的一些bug
这篇文章主要讲解了“Spring Boot集成接口管理工具Knife4j怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Spring Boot集成接口管理工具Knife4j怎么用”吧! 一…...
城电科技|光伏廊道是什么?安装光伏廊道有什么好处?
光伏廊道是什么?光伏廊道专门设计用于集中安装太阳能光伏发电系统的建筑物或构筑物,它可以将光伏转换成可以用于供电的清洁绿电。光伏廊道通常由阳能电池板、太阳能电池、控制器、逆变器、混凝土、钢材等材料组成,具备发电、坚固、耐用、防水…...
当DHCP服务器分配了同一个IP地址
当DHCP服务器分配了同一个IP地址给多个设备时,这通常会导致网络问题,如IP地址冲突,进而影响设备的网络连接。以下是详细的分析和解决步骤: 原因分析: IP地址租约未过期: 租约管理:DHCP服务器维…...
储能能量自动化调配装置功能介绍
随着可再生能源的快速发展,光伏发电已成为全球能源结构转型的关键技术之一。与此同时,储能技术作为实现光伏发电稳定输出的核心技术,得到了广泛关注。在企业电网中,光伏储能系统的运维管理不仅关乎能源利用效率,还涉及…...
vite5+vue3+Ts5 开源图片预览器上线
images-viewer-vue3:一款Vue3的轻量级图像查看器,它基于Flip动画技术,支持PC和h5移动网页预览照片,如果它是Vue3开发的产品。 npm开源地址:https://www.npmjs.com/package/images-viewer-vue3?activeTabreadme Flip 动画 < …...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
李沐--动手学深度学习--GRU
1.GRU从零开始实现 #9.1.2GRU从零开始实现 import torch from torch import nn from d2l import torch as d2l#首先读取 8.5节中使用的时间机器数据集 batch_size,num_steps 32,35 train_iter,vocab d2l.load_data_time_machine(batch_size,num_steps) #初始化模型参数 def …...
Java设计模式:责任链模式
一、什么是责任链模式? 责任链模式(Chain of Responsibility Pattern) 是一种 行为型设计模式,它通过将请求沿着一条处理链传递,直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者,…...
C#中用于控制自定义特性(Attribute)
我们来详细解释一下 [AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)] 这个 C# 属性。 在 C# 中,Attribute(特性)是一种用于向程序元素(如类、方法、属性等)添加元数据的机制。Attr…...
代理服务器-LVS的3种模式与调度算法
作者介绍:简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器,其中以Nginx为主,本章我们来讲解几个代理软件:…...
Centos 7 服务器部署多网站
一、准备工作 安装 Apache bash sudo yum install httpd -y sudo systemctl start httpd sudo systemctl enable httpd创建网站目录 假设部署 2 个网站,目录结构如下: bash sudo mkdir -p /var/www/site1/html sudo mkdir -p /var/www/site2/html添加测试…...
