十、组合模式
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式能够让客户端以统一的方式对待单个对象和对象集合,使得客户端在处理复杂树形结构的时候,可以以相同的方式对待单个对象和多个对象组合。

主要组成部分:
-
抽象组件(Component):
- 定义了 leaf 和 composite 的对象共同实现的接口。在这里你可以定义接口的方法。
-
叶子(Leaf):
- 实现了抽象组件,代表组合中的叶子节点。叶子节点没有子节点。
-
组合(Composite):
- 也实现了抽象组件,代表可以有子节点的树节点。组合节点可以包含叶子或其他组合节点。
-
客户端(Client):
- 使用组合结构的代码,通常通过接口与树结构交互。
优点:
- 一致性:客户端可以以一致的方式对待所有组成部分,无论是单个对象还是组合对象。
- 易于添加新组件:可以轻松地增加新的叶子或组合,无需修改现有代码。
- 简化客户端代码:客户端代码可以简单地使用组合结构,不需要关注部分和整体的区别。
使用场景:
- 需要表示对象的树形结构。
- 客户端希望以相同的方式处理单个对象和组合对象。
- 需要在运行时增加或删除对象。
JAVA:
创建一个文件系统的结构
// 文件系统-抽象组件
public abstract class FileSystemComponent {protected String name; //名称//构造public FileSystemComponent(String name){this.name = name;}//抽象文件详情方法public abstract void showDetails();
}
// 叶子类-文件
public class File extends FileSystemComponent{public File(String name) {super(name);}@Overridepublic void showDetails() {System.out.println("File: " + name);}
}
// 组合类
public class Folder extends FileSystemComponent{private List<FileSystemComponent> components = new ArrayList<>();public Folder(String name) {super(name);}// 添加文件/文件夹public void addComponent(FileSystemComponent component) {components.add(component);}// 删除文件public void removeComponent(FileSystemComponent component) {components.remove(component);}@Overridepublic void showDetails() {System.out.println("Folder: " + name);for (FileSystemComponent component : components) {component.showDetails();}}
}
@Test(description = "组合模式")public void compositeTest(){// 创建文件和文件夹File file1 = new File("File1.txt");File file2 = new File("File2.txt");Folder folder1 = new Folder("Folder1");folder1.addComponent(file1);folder1.addComponent(file2);File file3 = new File("File3.txt");Folder folder2 = new Folder("Folder2");folder2.addComponent(file3);// 创建根文件夹Folder rootFolder = new Folder("RootFolder");rootFolder.addComponent(folder1);rootFolder.addComponent(folder2);// 显示文件夹结构rootFolder.showDetails();}
GO:
公司的人员组织就是一个典型的树状的结构,现在假设我们现在有部分,和员工,两种角色,一个部门下面可以存在子部门和员工,员工下面不能再包含其他节点。
我们现在要实现一个统计一个部门下员工数量的功能
package composite// IOrganization 组织接口,都实现统计人数的功能
type IOrganization interface {Count() int
}// Employee 员工
type Employee struct {Name string
}// Count 统计人数
func (e Employee) Count() int {return 1
}// Department 部门
type Department struct {Name stringSubOrganizations []IOrganization
}// Count 人数统计
func (d Department) Count() int {c := 0for _, org := range d.SubOrganizations {c += org.Count()}return c
}// AddSub 添加子节点
func (d *Department) AddSub(o IOrganization) {d.SubOrganizations = append(d.SubOrganizations, o)
}// NewOrganization 构建组织架构 demo
func NewOrganization() IOrganization {root := &Department{Name: "root"}for i := 0; i < 10; i++ {root.AddSub(&Employee{})root.AddSub(&Department{Name: "sub", SubOrganizations: []IOrganization{&Employee{}}})}return root
}
package compositeimport ("github.com/stretchr/testify/assert""testing"
)func TestComposite(t *testing.T) {got := NewOrganization().Count()assert.Equal(t, 20, got)
}
相关文章:
十、组合模式
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式能够让客户端以统一的方式对待单个对象和对象集合,使得客户端在处理复杂树形结构的时候,可以以…...
一分钟了解网络安全风险评估!
网络安全风险评估是一种系统性的分析过程,旨在识别和评估网络系统中的潜在安全风险。这个过程包括识别网络资产、分析可能的威胁和脆弱性、评估风险的可能性和影响,以及提出缓解措施。网络安全风险评估有助于组织了解其网络安全状况,制定相应…...
【springsecurity】使用PasswordEncoder加密用户密码
目录 1. 导入依赖2. 配置 PasswordEncoder3. 使用 PasswordEncoder 加密用户密码4. 使用 PasswordEncoder 验证用户密码 1. 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifac…...
从0到1实现线程池(C语言版)
目录 🌤️1. 基础知识 ⛅1.1 线程概述 ⛅1.2 linux下线程相关函数 🌥️1.2.1 线程ID 🌥️1.2.2 线程创建 🌥️1.2.3 线程回收 🌥️1.2.4 线程分离 🌤️2. 线程池概述 ⛅2.1 线程池的定义 ⛅2.2 为…...
Visual studio自动添加头部注释
记事本打开VS版本安装目录下的Class.cs文件 增加如下内容:...
【C#生态园】提升性能效率:C#异步I/O库详尽比较和应用指南
优化异步任务处理:C#异步I/O库全面解析 前言 在C#开发中,异步I/O是一个重要的主题。为了提高性能和响应速度,开发人员需要深入了解各种异步I/O库的功能和用法。本文将介绍几个常用的C#异步I/O库,包括Task Parallel Library、Asy…...
管理医疗AI炒作的三种方法
一个人类医生和机器人医生互相伸手。 全美的医院、临床诊所和医疗系统正面临重重困难。他们的员工队伍紧张且人员短缺,运营成本不断上升,服务需求常常超过其承受能力,限制了医疗服务的可及性。 人工智能应运而生。在自ChatGPT推出将AI推向聚…...
VMware Workstation Pro Download 个人免费使用
参考 VMware Workstation Pro Download...
DevOps平台搭建过程详解--Gitlab+Jenkins+Docker+Harbor+K8s集群搭建CICD平台
一、环境说明 1.1CI/CD CI即为持续集成(Continue Integration,简称CI),用通俗的话讲,就是持续的整合版本库代码编译后制作应用镜像。建立有效的持续集成环境可以减少开发过程中一些不必要的问题、提高代码质量、快速迭代等;(Jenkins) CD即持续交付Con…...
Nginx之日志切割,正反代理,HTTPS配置
1 nginx日志切割 1.1 日志配置 在./configure --prefixpath指定的path中切换进去,找到log文件夹,进去后找到都是对应的日志文件 其中的nginx.pid是当前nginx的进程号,当使用ps -ef | grep nginx获得就是这个nginx.pid的值 在nginx.conf中…...
Mysql数据量大,如何拆分Mysql数据库(垂直拆分)
垂直拆分(Vertical Partitioning)是一种将数据库按照业务模块或功能进行拆分的方法,目的是将不同模块的数据放到不同的数据库中,从而减少单个数据库的压力,提高系统的性能和可扩展性。垂直拆分适用于数据量大且业务模块…...
机器人可能会在月球上提供帮助
登月是我们这个时代最具标志性的事件之一,这可能还算轻描淡写了:这是我们迄今为止在物理上探索得最远的一次。我听过一些当时的老广播,它们可以让你想象出这次航行的重要性。 现在,研究人员表示,我们可能很快就能重返…...
真实案例分享:零售企业如何避免销售数据的无效分析?
在零售业务的数据分析中,无效分析不仅浪费时间和资源,还可能导致错误的决策。为了避免这种情况,企业必须采取策略来确保他们的数据分析工作能够产生实际的商业价值。本文将通过行业内真实的案例,探讨零售企业如何通过精心设计的数…...
ctfshow-文件包含
web78 <?phpif(isset($_GET[file])){$file $_GET[file];include($file); }else{highlight_file(__FILE__); } 判断是否存在file参数 如果存在 将包含这个参数值 文件 php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执…...
Qt事件处理机制
用qt实现简单闹钟 widget.h #ifndef WIDGET_H #define WIDGET_H #include<QPushButton> #include<QTextEdit> #include<QLabel> #include <QWidget> #include<QMouseEvent> #include<QPoint> #include<QTime> #include<QTimer&…...
vue axios 如何读取项目下的json文件
在 Vue 项目中,使用 axios 读取本地的 JSON 文件可以通过将 JSON 文件放置在 public 目录中,然后通过 axios 发起请求读取。 步骤: 将 JSON 文件放置在 public 目录下: Vue 项目中的 public 目录是静态资源目录,项目编…...
燃气涡轮发动机性能仿真程序GSP12.0.4.2使用经验(二):使用GSP建立PG9351FA燃气轮机性能仿真模型
目录 一、PG9351FA燃气轮机简介及热力循环参数二、基于GSP的性能仿真模型设置环境参数设置进气道参数设置压气机参数设置燃烧室参数设置透平(涡轮)参数设置转子负载参数燃油流量外部控制 三、仿真结果四、其它 一、PG9351FA燃气轮机简介及热力循环参数 …...
迟滞比较器/施密特触发器
功能 从下面原理图像看来,只有在达到上下阈值才会出现输出电平的转换,这样防止信号的杂波跳变。而且每次的阈值是随着输出而变化的,当输出高时,阈值如下图中,V_PV_N V_R*( RF/(R1RF) )VH*( R1/(R1RF) );当输出低时&a…...
LeetCode_sql_day22(1112.每位学生的最高成绩)
描述:1112.每位学生的最高成绩 表:Enrollments ------------------------ | Column Name | Type | ------------------------ | student_id | int | | course_id | int | | grade | int | ------------------------ (st…...
OFDM信号PARP的CCDF图
文章目录 引言代码代码疑难解答参考文献 引言 本书主要参考了文献1,但实际上该书中符号和表述的错误非常多(只能说棒子是这样的);同时因为发表时间的关系,很多MATLAB代码进行了更新,原书提供的代码已经无法…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
C++中vector类型的介绍和使用
文章目录 一、vector 类型的简介1.1 基本介绍1.2 常见用法示例1.3 常见成员函数简表 二、vector 数据的插入2.1 push_back() —— 在尾部插入一个元素2.2 emplace_back() —— 在尾部“就地”构造对象2.3 insert() —— 在任意位置插入一个或多个元素2.4 emplace() —— 在任意…...
