Composite(组合)
1)意图
将对象组合成树型结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。
2)结构
组合模式的结构如图 7-33 所示。

其中:
- Component 为组合中的对象声明接口;在适当情况下实现所有类共有接口的默认行为;声明一个接口用于访问和管理 Component 的子组件;(可选)在递归结构中定义一个接口,用于访问一个父组件,并在合适的情况下实现它。
- Leaf在组合中表示叶结点对象,叶结点没有子结点:在组合中定义图元对象的行为。
- Composite 定义有子组件的那些组件的行为;存储子组件;在Component 接口中实现与子组件有关的操作。
- Client 通过 Component 接口操纵组合组件的对象。
3)适用性
Composite 模式适用于:
- 想表示对象的部分-整体层次结构。
- 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
4 应用举例
示例:文件系统中的目录和文件
创建了一个简单的文件系统模型,其中Directory可以包含其他Directory或File,而File则不能包含其他元素。通过这种方式,可以很容易地构建出复杂的文件系统结构,并且客户端可以通过相同的接口操作单个文件或整个目录树。
1. Component (组件)
public abstract class FileSystemEntry {protected String name;public FileSystemEntry(String name) {this.name = name;}public abstract int getSize();public abstract void printList(String prefix);
}
在这个例子中,FileSystemEntry 类充当了组件的角色。它是所有文件系统条目的基类,无论是文件还是目录。这个类定义了一些公共的行为,比如 getSize() 和 printList(String prefix) 方法,这些方法在所有的文件系统条目中都是通用的。
getSize():返回文件或目录的大小。对于文件,它直接返回文件的大小;对于目录,它需要计算所有子项的总大小。printList(String prefix):打印出文件或目录的信息,以及它们在文件系统中的路径。这里的prefix参数是用来构建路径的,当打印一个目录时,会递归地调用其子项的printList()方法,从而构建出完整的路径。
2. Leaf (叶子节点 - 文件)
public class File extends FileSystemEntry {private int size;public File(String name, int size) {super(name);this.size = size;}@Overridepublic int getSize() {return size;}@Overridepublic void printList(String prefix) {System.out.println(prefix + "/" + this);}@Overridepublic String toString() {return "File (" + name + ", " + size + " bytes)";}
}
File 类是叶子节点的具体实现。它代表文件系统中的一个文件,不包含任何子节点。因此,它的 add() 和 remove() 操作是没有意义的,所以在 File 类中不需要实现这些方法。File 类主要实现了 getSize() 和 printList(String prefix) 方法,分别用来返回文件的大小和打印文件信息。
3. Composite (组合节点 - 目录)
import java.util.ArrayList;
import java.util.List;public class Directory extends FileSystemEntry {private List<FileSystemEntry> children = new ArrayList<>();public Directory(String name) {super(name);}public void add(FileSystemEntry entry) {children.add(entry);}public void remove(FileSystemEntry entry) {children.remove(entry);}@Overridepublic int getSize() {int totalSize = 0;for (FileSystemEntry child : children) {totalSize += child.getSize();}return totalSize;}@Overridepublic void printList(String prefix) {System.out.println(prefix + "/" + this);String newPrefix = prefix.isEmpty() ? name : prefix + "/" + name;for (FileSystemEntry child : children) {child.printList(newPrefix);}}@Overridepublic String toString() {return "Directory (" + name + ", " + getSize() + " bytes)";}
}
Directory 类是组合节点的具体实现。它代表文件系统中的一个目录,可以包含多个文件和其他目录。Directory 类中有一个 children 列表,用于存储目录下的所有子节点。
add(FileSystemEntry entry):向目录中添加一个新的子节点。remove(FileSystemEntry entry):从目录中移除一个子节点。getSize():遍历children列表,累加每个子节点的大小,最终返回目录的总大小。printList(String prefix):首先打印当前目录的信息,然后递归地调用每个子节点的printList(String prefix)方法,构建并打印出子节点的完整路径。
4. Client (客户端)
public class Client {public static void main(String[] args) {// 创建文件和目录File file1 = new File("file1.txt", 1024);File file2 = new File("file2.txt", 2048);Directory dir1 = new Directory("dir1");Directory dir2 = new Directory("dir2");// 添加文件到目录dir1.add(file1);dir1.add(file2);dir2.add(dir1);// 打印目录结构dir2.printList("");}
}
在 Client 类的 main 方法中,我们创建了几个文件和目录,并将它们组织成一个树形结构。通过调用 printList("") 方法,我们可以看到整个文件系统的结构和每个文件或目录的大小。
这段代码创建了一个简单的文件系统模型,其中Directory可以包含其他Directory或File,而File则不能包含其他元素。通过这种方式,可以很容易地构建出复杂的文件系统结构,并且客户端可以通过相同的接口操作单个文件或整个目录树。
运行结果
假设我们运行上面的客户端代码,输出可能如下所示:
/Directory (dir2, 3072 bytes)
/dir2/Directory (dir1, 3072 bytes)
/dir2/dir1/File (file1.txt, 1024 bytes)
/dir2/dir1/File (file2.txt, 2048 bytes)
这表明:
dir2是最外层的目录,总大小为 3072 字节。dir2下有一个子目录dir1,dir1的总大小也是 3072 字节。dir1包含两个文件file1.txt和file2.txt,大小分别为 1024 字节和 2048 字节。
组合模式的关键在于它可以让你以一致的方式处理单个对象和对象的组合。这意味着你可以用相同的方式来操作文件和目录,而不需要关心它们是单个文件还是包含多个子项的目录。这种设计模式在处理具有层次结构的数据时非常有用,例如文件系统、图形用户界面的组件树等。
相关文章:
Composite(组合)
1)意图 将对象组合成树型结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性。 2)结构 组合模式的结构如图 7-33 所示。 其中: Component 为组合中的对象声明接口;在适当情况下实现所有类共有接口的默认行为;声明一个接口用于访问…...
有Bootloader,为什么还要BROM?
有Bootloader,为什么还要BROM? 不少硬件平台都提供类似Boot ROM或者PBL(高通平台)固化的一段程序,出厂后用户一定不能修改。BROM可以引导Bootloader程序。大家知道,每个可启动的平台都会在存储设备,例如EMMC/NAND/UFS保存Bootloa…...
【MATLAB代码】CV和CA模型组成的IMM(滤波方式为UKF),可复制粘贴源代码
该MATLAB代码实现了基于无迹卡尔曼滤波器(UKF)的交互式多模型(IMM)滤波算法,旨在跟踪目标在不同运动模式(匀速直线运动CV和匀速圆周运动CT)的位置和速度。订阅专栏后,直接复制粘贴代码到MATLAB空脚本中,即可运行 文章目录 运行结果源代码程序介绍1. 初始化和参数设定2…...
【网络】传输层协议TCP(下)
目录 四次挥手状态变化 流量控制 PSH标记位 URG标记位 滑动窗口 快重传 拥塞控制 延迟应答 mtu TCP异常情况 四次挥手状态变化 之前我们讲了四次挥手的具体过程以及为什么要进行四次挥手,下面是四次挥手的状态变化 那么我们下面可以来验证一下CLOSE_WAIT这…...
服务器数据恢复—EVA存储故障导致上层应用不可用的数据恢复案例
服务器存储数据恢复环境: 一台EVA某型号控制器EVA扩展柜FC磁盘。 服务器存储故障&检测: 磁盘故障导致该EVA存储中LUN不可用,导致上层应用无法正常使用。 服务器存储数据恢复过程: 1、将所有磁盘做好标记后从扩展柜中取出。硬…...
支持向量机相关证明 解的稀疏性
主要涉及拉格朗日乘子法,对偶问题求解...
静态ip和动态ip适合什么场景
静态住宅ip由于他的ip位置保持不变的,更加适合: 1、账号管理。 使用静态住宅来注册和管理社交媒体账号,例如facebook、领英等,包括电商类的账号也是可以的,例如亚马逊等 2、网站测试 很多网站会检测使用者是否为机器…...
Istio Gateway发布服务
1. Istio Gateway发布服务 在集群中部署一个 tomcat 应用程序。然后将部署一个 Gateway 资源和一个与 Gateway 绑定的 VirtualService,以便在外部 IP 地址上公开该应用程序。 1.1 部署 Gateway 资源 vim ingressgateway.yaml --- apiVersion: networking.istio.…...
前端vue3若依框架pnpm run dev启动报错
今天前端vue3若依框架pnpm run dev启动报错信息: > ruoyi3.8.8 dev D:\AYunShe\2024-11-6【无锡出门证】\wuxi-exit-permit-web > vite error when starting dev server: Error: listen EACCES: permission denied 0.0.0.0:80 at Server.setupListenHand…...
python线条爱心
效果图 代码 import math from turtle import * def hearta(k):return 15*math.sin(k)**3 def heartb(k):return 12*math.cos(k)-5*\math.cos(2*k)-2*\math.cos(3*k)-\math.cos(4*k) speed(1000) bgcolor("black") for i in range(6000):goto(hearta(i)*20,heartb(…...
GPU的内存是什么?
GPU(图形处理器)的内存是指专门用于 GPU 存储数据的内存,也被称为显存。 一、显存的作用: 1、存储图像数据 当计算机要显示图像时,显存会存储屏幕上每个像素点的颜色、亮度等信息。例如,对于一个分辨率为 1…...
Linux - 弯路系列1:xshell能够连接上linux,但xftp连不上(子账号可以连接,但不能上传数据)
问题如题目阐述。 注:所有操作在root账户下操作。 解决办法: 1、确认连接设置 服务器地址和端口:确保在 Xftp 中输入的服务器地址和端口号与 Xshell 使用的相同。默认情况下,SFTP 使用端口 22。 用户凭证:检查用户名…...
数组逆序重存放
题目描述 将一个数组中的值按逆序重新存放。例如,原来的顺序为8,6,5,4,1。要求改为1,4,5,6,8。 输入 输入为两行:第一行数组中元素的个数n(1<n<100),第二行是n个整数,每两个整数之间用空格分隔。 输出 输出…...
归并排序:高效算法的深度解析
一、归并排序概述 归并排序是一种基于分治思想的经典排序算法。它的核心操作分为三个主要步骤:分割、排序和合并。 首先是分割步骤,将待排序的数组不断地分成更小的子数组,直到每个子数组中只有一个元素。例如,对于一个包含多个…...
微服务中常用分布式锁原理及执行流程
1.什么是分布式锁 分布式锁是一种在分布式系统环境下实现的锁机制,它主要用于解决,多个分布式节点之间对共享资源的互斥访问问题,确保在分布式系统中,即使存在有多个不同节点上的进程或线程,同一时刻也只有一个节点可…...
声学气膜馆助力企业年会与研学活动完美呈现—轻空间
在现代企业和教育活动中,场地的选择往往决定了活动的成败。尤其是在企业年会、研学基地等重要场合,选择一个既能满足多功能需求又能快速搭建的场地至关重要。而声学气膜馆正是为这种需求量身打造的理想场所。凭借其独特的声学性能和灵活的结构设计&#…...
Halcon3D image_points_to_world_plane详解
分三个部分来聊聊这个算子 一,算子的参数介绍 二,算法的计算过程 三,举例实现 第一部分,算子的介绍 image_points_to_world_plane( : : CameraParam, WorldPose, Rows, Cols, Scale : X, Y) 参数介绍: CameraParam,:相机内参 WorldPose 世界坐标系,也叫物体坐标系(成…...
A Consistent Dual-MRC Framework for Emotion-cause Pair Extraction——论文阅读笔记
前言 这是我第一次向同学院同年级的学生和老师们汇报的第一篇论文,于2022年发表在TOIS上,属于CCF A类,主要内容是将MRC应用到情感原因对抽取中。 论文链接:用于情绪-原因对提取的一致双 MRC 框架 |信息系统上的 ACM Transactions 这里我就不放上我自己翻译的中文版还有我…...
如何debug(Eclipse)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 2分钟教会你如何Java中DeBug【IDEA中Java】 在eclipse中如何使用Debug进行调试 双击左侧打断点(取消断点同样双击) 右上角进入debug界面(常用) 选择所需断点位置(勾选右侧需要测试的断点位置) 启动…...
【comfyui教程】ComfyUI有趣工作流推荐:快速换脸,创意随手掌握!
前言 在数字影像处理和创意表达领域,ComfyUI 绝对是你的得力助手!今天我们推荐一个非常有趣的工作流——快速换脸。无论你是图像编辑小白,还是深耕AI影像的达人,这个工作流都能让你快速实现面部迁移,体验全新的照片玩…...
5秒批量打开20个网页?这款效率工具让多任务处理快到飞起
5秒批量打开20个网页?这款效率工具让多任务处理快到飞起 【免费下载链接】Open-Multiple-URLs Browser extension for opening lists of URLs built on top of WebExtension with cross-browser support 项目地址: https://gitcode.com/gh_mirrors/op/Open-Multip…...
AI产品经理崛起:技术人转型的新风口
技术浪潮下的职业新机遇人工智能(AI)技术的爆炸式发展正重塑全球产业格局,催生出一系列新兴职业。其中,AI产品经理(AI PM)作为连接技术与商业的桥梁,已成为当下最炙手可热的岗位。数据显示&…...
腾讯混元翻译模型惊艳展示:HY-MT1.5-1.8B多语言翻译案例集
腾讯混元翻译模型惊艳展示:HY-MT1.5-1.8B多语言翻译案例集 1. 引言:当翻译遇见大模型,语言不再是障碍 想象一下,你正在阅读一篇最新的科技论文,原文是英文,但你的母语是中文。或者,你收到一封…...
别再手动装依赖了!ROS 2 Humble/Foxy下用rosdep一键搞定工作空间所有包的依赖安装
别再手动装依赖了!ROS 2 Humble/Foxy下用rosdep一键搞定工作空间所有包的依赖安装 "又报错了?缺少libxxx-dev?"——这可能是ROS 2开发者最常遇到的崩溃瞬间。当你在深夜赶项目,colcon build却因为缺失依赖而中断时&…...
3个AI工具如何提升动态图像质量?专业级画质增强全攻略
3个AI工具如何提升动态图像质量?专业级画质增强全攻略 【免费下载链接】video2x A lossless video/GIF/image upscaler achieved with waifu2x, Anime4K, SRMD and RealSR. Started in Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/…...
3000+开源蓝图:革新性一站式戴森球计划工厂解决方案
3000开源蓝图:革新性一站式戴森球计划工厂解决方案 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints 面对戴森球计划中错综复杂的生产线布局,你是否曾…...
从CVE-2023-3450看锐捷RG-BCR860路由器:一次网络诊断功能引发的命令注入实战剖析
1. 漏洞背景与设备介绍 锐捷RG-BCR860是面向中小型商业场景设计的云路由器,主打简单易用的中文Web管理界面。这款设备常见于连锁餐饮、快捷酒店等需要稳定网络环境的场所,最大支持150台终端同时接入。作为一款商用设备,它内置了安全审计模块和…...
QQ空间历史说说备份终极攻略:3步实现数据永久保存
QQ空间历史说说备份终极攻略:3步实现数据永久保存 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory GetQzonehistory是一款专为QQ空间用户设计的开源数据备份工具,…...
nRF Connect扫描功能保姆级教程:从过滤广播数据到分析RSSI信号图,手把手教你精准定位蓝牙设备
nRF Connect扫描功能实战指南:从设备筛选到信号优化的全流程解析 当你面对展会现场上百个闪烁的蓝牙设备指示灯,或是实验室里数十个同型号的传感器节点时,如何快速锁定目标设备就像大海捞针。nRF Connect作为蓝牙开发者的瑞士军刀,…...
大语言模型+进化算法:LLM-LNS如何解决传统MILP优化难题?
大语言模型与进化算法融合:LLM-LNS如何重塑复杂优化问题求解范式 当在线零售商需要实时优化数万个包裹的装箱方案,或是物流公司面临百万级城市的路径规划时,传统优化算法往往陷入"维度灾难"的困境。混合整数线性规划(M…...
