十、组合模式

news2024/9/20 13:43:41

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

主要组成部分:

  1. 抽象组件(Component)

    • 定义了 leaf 和 composite 的对象共同实现的接口。在这里你可以定义接口的方法。
  2. 叶子(Leaf)

    • 实现了抽象组件,代表组合中的叶子节点。叶子节点没有子节点。
  3. 组合(Composite)

    • 也实现了抽象组件,代表可以有子节点的树节点。组合节点可以包含叶子或其他组合节点。
  4. 客户端(Client)

    • 使用组合结构的代码,通常通过接口与树结构交互。

优点:

  1. 一致性:客户端可以以一致的方式对待所有组成部分,无论是单个对象还是组合对象。
  2. 易于添加新组件:可以轻松地增加新的叶子或组合,无需修改现有代码。
  3. 简化客户端代码:客户端代码可以简单地使用组合结构,不需要关注部分和整体的区别。

使用场景:

  • 需要表示对象的树形结构。
  • 客户端希望以相同的方式处理单个对象和组合对象。
  • 需要在运行时增加或删除对象。

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);
    }

    @Override
    public 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);
    }

    @Override
    public 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             string
	SubOrganizations []IOrganization
}

// Count 人数统计
func (d Department) Count() int {
	c := 0
	for _, 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 composite

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestComposite(t *testing.T) {
	got := NewOrganization().Count()
	assert.Equal(t, 20, got)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123877.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

读者来信:《人机环境系统智能》读后感

一、什么是智能&#xff1f; 当“人工智能”火爆出圈乃至登堂入室&#xff0c;上升为国家战略层面后&#xff0c;尽管我们每天都把人工智能挂在嘴上&#xff0c;但好像似乎忘了问一句&#xff1a;什么是智能&#xff1f;经过一番在哲学上对控制论、信息论、系统论在哲学上的追根…

MES实施困难点简述

调研数据显示&#xff0c;企业认为多部门协调难度大、各类数据采集难度大、定制化程度高是MES系统实施过程中最为突出的三个难点&#xff0c;比例分别达到52%、48%、46%。其他如对MES认识不足、难以准确把握需求、企业相关人才比较匮乏、与其他系统边界难以划分等也是实施过程中…

加密与安全_优雅存储用户密码的最佳实践

文章目录 Pre概述最佳实践避免使用MD5、SHA1等快速哈希算法加盐哈希 &#xff08;不推荐&#xff09;使用BCrypt、Argon2等慢哈希算法 (推荐)BCrypt Code1. 自动生成和嵌入盐2. 哈希结果的格式3. 代价因子 BCrypt特点 防止暴力破解1. 登录失败锁定2. 双因素认证&#xff08;2FA…

MATLAB | 绘图复刻(十七) | 半小提琴图

嘿&#xff0c;真的是好久不见&#xff0c;最近有点过于忙了&#xff0c;今天更一个好久之前粉丝问的半小提琴图的绘制方法&#xff0c;要复刻这张图&#xff1a; 绘制效果如下&#xff1a; 还是挺好看的&#xff0c;下面直接进入正题&#xff1a; 教程部分 0 数据准备 这里…

Redis学习Day3——项目工程开发

扩展阅读推荐&#xff1a; 黑马程序员Redis入门到实战教程_哔哩哔哩_bilibili 一、项目介绍及其初始化 学习Redis的过程&#xff0c;我们还将遇到各种实际问题&#xff0c;例如缓存击穿、雪崩、热Key等问题&#xff0c;只有在实际的项目实践中解决这些问题&#xff0c;才能更好…

DPDI基础版安装部署说明

DispatchPDI下载 DPDI online部署包下载地址&#xff1a; Windows: http://files.pizzalord.site/api/public/dl/7Tnq6ScE/release/dpdi-community-win.zip Linux: http://files.pizzalord.site/api/public/dl/otCt9WuI/release/dpdi-community-linux.zip DPDI部署 DPDI应…

python构建深度学习模型开发数据采集利器,为模型提供充足图像数据

经常需要接触到各种各样的图像数据&#xff0c;为模型开发准备素材&#xff0c;在实际的项目中&#xff0c;一部分数据来源于真实的项目场景&#xff0c;但是这部分数据大都比较少&#xff0c;且获取的难度比较大&#xff0c;往往都是项目到了实施阶段的时候才有机会拿到数据&a…

基于SpringBoot的医院挂号预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的医院挂号预约管理…

【有啥问啥】探索扫地机器人中的 SLAM 算法:原理、实现与未来展望

探索扫地机器人中的 SLAM 算法&#xff1a;原理、实现与未来展望 随着智能家居的普及&#xff0c;扫地机器人逐渐成为日常生活中的常见家电。其自主导航能力使得它能够在复杂的家庭环境中高效完成清洁任务&#xff0c;而这背后的核心技术之一就是 SLAM&#xff08;Simultaneou…

CCS12.2 以及以上版本如何使用C2000ware 4.03版本,发现直接导入工程不能正确识别地址变量?

C2000ware 5.02 地址变量为&#xff1a;COM_TI_C2000WARE_INSTALL_DIR&#xff0c;CCS12.2以上版本能够直接匹配识别&#xff01; 但是C2000ware4.03版本地址变量为&#xff1a;COM_TI_C2000WARE_SOFTWARE_PACKAGE_INSTALL_DIR&#xff0c;这个不能直接识别到头文件的地址&…

appium server gui详细按照步骤

1.安装appium server desktop Appium安装提供两种方式:桌面版和命令行版。其中桌面版又分为 Appium GuI 和 Appium Desktop 。作为初学者&#xff0c;用桌面版&#xff0c;对初学者比较友好。 官网下载地址&#xff1a;Releases appium/appium-desktop GitHubTags appium/…

基于FPGA与RK3588的多通道低延时3G-SDI视频信号

目录 简介 主要用途&#xff1a; 项目简介&#xff1a; 详细过程&#xff1a; BT1120视频时序转CEA861 视频像素编码格式转换 低延时处理 MIPI接口处理 视频处理模块 ​​​​​​​ 简介 主要解决 RK3588支持多种视频格式输入&#xff0c;但是没有支持多路SDI接口的…

【JUC】14-LongAddr源码分析

1. LongAddr底层实现过程 2. Striped64中变量或方法的定义 base&#xff1a;类似于AtomicLong中全局的value值。在没有竞争情况下数据直接累加到base上&#xff0c;或者cells扩容时&#xff0c;也需要将数据写入到base上。collide&#xff1a;表示扩容意向&#xff0c;false一…

反转链表 II

题目 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&#xff1a;…

Java中的ArrayList类

继承实现关系 Arraylist就是一个可以动态扩容的容器&#xff0c;属于集合类的一种&#xff0c;要追根溯源的话它是间接实现了Collection接口&#xff0c;下面我画一下它的结构图 类定义 ArrayList类继承自抽象类AbstractList&#xff0c;同时实现了List和Collection接口&…

服务器数据恢复—通过拼接数据库碎片的方式恢复SQL Server数据库数据

服务器数据恢复环境&#xff1a; 一台服务器中有一组由4块STAT硬盘通过RAID卡组建的RAID10阵列&#xff0c;上层是XenServer虚拟化平台&#xff0c;虚拟机安装Windows Server操作系统&#xff0c;作为Web服务器使用。 服务器故障&#xff1a; 因机房异常断电导致服务器中一台V…

元学习之应用案例

现在在做元学习的时候&#xff0c;我们最常拿来测 试元学习技术的任务叫做少样本图像分类&#xff0c;简单来讲就是每一个任务都只有几张图片&#xff0c;每一 个类别只有几张图片。比如我们使用图1的案例为例说明。现在分类的任务是分为三个 类别&#xff0c;每个类别都只有两…

贪心-用最少的箭射球

一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭&#xff0c;若有一个气球的直径的开始和结束坐标为 xstart&#xff0c;xend&#xff0c; 且满足 xstart ≤ x ≤ xend&#xff0c;则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后…

MySQL从C盘迁移到D盘

文章目录 前言一、停止MySQL服务打开服务&#xff08;方式一&#xff09;打开服务&#xff08;方式二&#xff09;停止MySQL服务 二、找到C盘中的文件文件夹1文件夹2文件夹3 三、修改文件内容1.对应文件夹12.对应文件夹3 四、 修改注册表中文件路径1.打开注册表2. 修改注册表中…

微积分-积分应用5.5(函数的平均值)

很容易计算有限多个数字 y 1 , y 2 , … , y n y_1, y_2, \dots, y_n y1​,y2​,…,yn​ 的平均值&#xff1a; y ave y 1 y 2 ⋯ y n n y_{\text{ave}} \frac{y_1 y_2 \cdots y_n}{n} yave​ny1​y2​⋯yn​​ 但是&#xff0c;如果可以进行无限多次的温度读取&…