当前位置: 首页 > news >正文

C# 设计模式(结构型模式):组合模式

C# 设计模式(结构型模式):组合模式

在软件设计中,有时我们需要处理的是一组对象,而这些对象既可以是单独的元素,也可以是由多个子元素组成的复合体。这时,组合模式(Composite Pattern)便能提供帮助。它允许客户端将单个对象和对象集合统一对待,从而简化了树形结构的管理。

1. 组合模式的定义

组合模式是一个结构型设计模式,主要用于将多个对象组合成树形结构,以表示“部分-整体”的层次关系。通过组合模式,客户端可以以一致的方式对待单个对象和对象集合,而无需关心它们的具体结构。这使得客户端的代码更加简洁和易于维护。

2. 组合模式的结构

组合模式通常由以下几个部分组成:

  • Component(组件接口):定义了叶子节点和组合节点的公共接口,通常包含一些通用的操作方法。
  • Leaf(叶子节点):表示树形结构中的叶子节点,它是没有子节点的最基本单元。
  • Composite(组合节点):表示树形结构中的非叶子节点,它可以包含子节点,可以是其他的组合节点或者叶子节点。
  • Client(客户端):调用组合模式接口的客户端,它无需知道节点是单一对象还是组合对象。
3. 组合模式的应用场景

组合模式适用于以下几种场景:

  • 当你需要表示对象的“部分-整体”层次结构时。
  • 当客户端需要统一对待单个对象和对象集合时。
  • 当树形结构的元素和子元素的处理方式相同,可以用组合模式统一处理。
4. C# 实现组合模式

假设我们要设计一个公司组织结构系统,其中包括了员工(叶子节点)和部门(组合节点)。每个部门可以包含多个员工,或者其他的子部门。我们希望能够统一管理员工和部门,无论它们是单独的员工还是子部门。

using System;
using System.Collections.Generic;// 组件接口
public interface IEmployee
{void ShowDetails();
}// 叶子节点:员工
public class Employee : IEmployee
{private string name;private string position;public Employee(string name, string position){this.name = name;this.position = position;}public void ShowDetails(){Console.WriteLine($"{name} - {position}");}
}// 组合节点:部门
public class Department : IEmployee
{private string departmentName;private List<IEmployee> employees = new List<IEmployee>();public Department(string departmentName){this.departmentName = departmentName;}public void AddEmployee(IEmployee employee){employees.Add(employee);}public void RemoveEmployee(IEmployee employee){employees.Remove(employee);}public void ShowDetails(){Console.WriteLine($"Department: {departmentName}");foreach (var employee in employees){employee.ShowDetails();}}
}// 客户端代码
class Program
{static void Main(string[] args){// 创建员工IEmployee emp1 = new Employee("Alice", "Developer");IEmployee emp2 = new Employee("Bob", "Tester");// 创建部门Department techDept = new Department("Technology");techDept.AddEmployee(emp1);techDept.AddEmployee(emp2);// 创建更多员工IEmployee emp3 = new Employee("Charlie", "Developer");IEmployee emp4 = new Employee("David", "Manager");// 创建另一个部门Department hrDept = new Department("HR");hrDept.AddEmployee(emp3);hrDept.AddEmployee(emp4);// 创建总公司Department company = new Department("MyCompany");company.AddEmployee(techDept);company.AddEmployee(hrDept);// 显示公司所有信息company.ShowDetails();}
}

在这个例子中:

  • IEmployee 是组件接口,定义了员工和部门的公共接口。
  • Employee 类是叶子节点,表示公司中的一个员工。
  • Department 类是组合节点,表示一个部门,可以包含多个员工或者其他子部门。
  • ShowDetails 方法展示了员工和部门的详细信息。

通过组合模式,我们可以轻松地构建一个树形结构的公司组织架构,并且统一处理员工和部门,无论它们是单独的员工还是包含多个员工的部门。

5. 组合模式的优缺点

优点

  • 简化客户端代码:客户端可以统一对待单一对象和对象集合,减少了代码的复杂性。
  • 灵活扩展:可以通过增加新的叶子节点或组合节点来扩展树形结构,而不需要修改客户端代码。
  • 树形结构的自然表达:组合模式非常适合表示“部分-整体”层次结构,如公司组织、文件夹结构等。

缺点

  • 增加了类的数量:组合模式可能会导致系统中类的数量增加,特别是在树形结构非常复杂的情况下。
  • 难以限制叶子节点的行为:在某些情况下,叶子节点和组合节点的行为可能会变得非常相似,这会导致设计上的一些困难。
6. 总结

组合模式是一个非常强大的设计模式,尤其适用于处理“部分-整体”结构的场景。通过组合模式,客户端能够以统一的方式对待单个对象和对象集合,从而简化了复杂系统的管理。无论是公司组织结构、文件系统还是图形界面,组合模式都能提供优雅的解决方案。


相关文章:

C# 设计模式(结构型模式):组合模式

C# 设计模式&#xff08;结构型模式&#xff09;&#xff1a;组合模式 在软件设计中&#xff0c;有时我们需要处理的是一组对象&#xff0c;而这些对象既可以是单独的元素&#xff0c;也可以是由多个子元素组成的复合体。这时&#xff0c;组合模式&#xff08;Composite Patte…...

Aloudata AIR | 逻辑数据平台的 NoETL 之道

一文为你介绍 Aloudata AIR 逻辑数据平台的技术原理与核心价值 本文主旨是介绍逻辑数据平台的技术原理与核心价值&#xff0c;包含几个部分的内容&#xff1a; 首先&#xff0c;简要阐述逻辑数据平台出现的背景&#xff1b;其次&#xff0c;详细讲解逻辑数据平台的构建方法&am…...

js的一些处理

1.翻转字符串 let str abcdef str str.split().reverse().join() console.log(str) 因此想到了我之前写的截取字符串获取参数跳转&#xff0c;在写一遍 let str nameJack&age18&gender男 let list str.split(&); let obj {} list.forEach((v)>{ …...

NLP 复习大纲

CH3 激活函数意义 增强网络表达能力&#xff0c;引入非线性因素 连续可导的非线性函数 尽可能简单 导数的值域要在合适的范围内 为什么会发生梯度消失 误差传播的迭代公式为&#xff1a; 其中需要用到激活函数的导数&#xff0c;而激活函数的导数值小于1时&#xff0c;误差经过…...

Kafka的rebalance机制

1、什么是 rebalance 机制 重平衡&#xff08;rebalance&#xff09;机制规定了如何让消费者组下的所有消费者来分配 topic 中的每一个分区。 2、rebalance 机制的触发条件是什么 &#xff08;1&#xff09;消费者组内成员变更 成员增加&#xff1a;当有新的消费者加入到消费…...

【git】git stash相关指令

目录 git stashgit stash save “”git stash list&#xff1a; 获取stash列表git stash pop&#xff1a;恢复最近一次stash缓存git stash apply stash{index}: 恢复指定缓存在这里插入图片描述git stash drop stash{1}&#xff1a;删除指定缓存 git stash clear :删除stash gi…...

BLIP论文笔记

论文地址 BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation 论文思想 其实Clip就相当于只用了ITC...

设计模式-创建型设计模式总结

创建型设计模式&#xff08;Creational Design Patterns&#xff09;是 设计模式 中的一类&#xff0c;专注于如何实例化对象或类。它们提供了一些优雅的方式来创建对象&#xff0c;允许程序在对象创建过程中更灵活地进行管理&#xff0c;从而提高系统的扩展性和维护性。 创建…...

Java-多种方法实现多线程卖票

Java多线程卖票是一个经典的并发编程问题,它展示了如何在多个线程之间安全地共享和修改资 源。以下是几种实现方式: 使用synchronized关键字: 使用synchronized修饰符来同步方法或代码块,确保同一时刻只有一个线程可以访问临界区(即操 作共享资源的代码)。 使用Reen…...

嵌入式系统开发笔记112:通过有人云测试MQTT

文章目录 前言一、MQTT1、基本原理(1)发布 / 订阅模式:(2)主题系统:2、特点(1)轻量级:(2)可靠性:(3)低功耗:3、消息主题的命名(1)使用正斜杠(/)分隔层级:(2)区分大小写:(3)避免特殊字符:4、客户端ID(1)作用a、连接标识:b、消息路由与管理:c、会话…...

C++ Latch 和 Barrier: 新手指南

文章目录 什么是 Latch 和 Barrier?为什么要使用 Latch 和 Barrier?代码示例示例 1: 使用 std::latch示例 2: 多阶段任务示例 3: 使用 std::barrier 何时使用?优势使用时需要注意的事项参考链接源码链接 随着并发和并行编程的重要性日益增加, 理解像 Latch 和 Barrier 这样的…...

【Cocos TypeScript 零基础 4.1】

目录 背景滚动 背景滚动 创建一个 空节点 背景丟进去 ( 复制一个,再丢一次都行) 新建TS脚本 并绑定到 空节点 上 再对TS脚本进行编辑 export class TS2bg extends Component {property (Node) // 通过属性面板去赋值bg1:Node nullproperty (Node) bg2:Node nullprope…...

区块链安全常见的攻击合约和简单复现,附带详细分析——不安全调用漏洞 (Unsafe Call Vulnerability)【6】

区块链安全常见的攻击分析——不安全调用漏洞 Unsafe Call Vulnerability 1.1 漏洞合约1.2 漏洞分析1.3 攻击步骤分析1.4 攻击合约 Name: 不安全调用漏洞 (Unsafe Call Vulnerability) 重点&#xff1a; 在 TokenWhale 合约的 approveAndCallcode 函数中&#xff0c;漏洞允许任…...

鸿蒙应用开发搬砖经验之—使用ArkWeb要开启文档对象模型存储接口权限(DOM Storage API权限)

如题&#xff0c;该属性/功能默认是没有开启的&#xff01;&#xff01;&#xff01;&#xff01; 所以需要我们手动开启&#xff0c;否侧加载的H5 SPA大概率功能不正常&#xff0c;因为现在大多数的H5应用都用遇到对象模型存储的功能&#xff0c;对应的接口是 不开启一般会…...

本机实现Llama 7B推理及部署

本机实现Llama 7B推理及部署 使用llamafile在Windows系统部署 部署步骤:首先从https://www.modelscope.cn/api/v1/models/bingal/llamafile-models/repo?Revision=master&FilePath=llamafile-0.6.2.win.zip下载llamafile并解压得到llamafile.exe文件, 再从https://www.…...

Spring Boot 依赖配置分离多种打包方式

生产上发布 Spring Boot 项目时,但凡代码有一丁点改动,就得把整个项目包括依赖重新打包上传部署,这样的包很大,影响效率 为解决这个问题,可以把依赖(pom中的依赖jar包)、配置文件(resources 下的 applacation.yml 等文件)从项目主体里剥离出来,后续部署时,只需发布代…...

华为的数字化转型框架和数字化转型成熟度评估方法

2016年&#xff0c;华为公司数字化转型变革规划汇报通过&#xff0c;一系列的变革项目由变革指导委员会(Executive Steering Committee,ESC)完成立项。8年多来&#xff0c;华为数字化转型工作初步取得了一些成果&#xff0c;比如&#xff1a; 实现“销售收入翻番&#xff0c;但…...

图像转换 VM与其他格式互转

目录 前言 图像转换 1.相机取流转VM对应类型图像格式 1.1 相机采图转流程输入和Group输入(ImageBaseData_V2) 1.2 相机采图转图像源SDK输入(ImageBaseData) 1.3 相机采图转模块输入(InputImageData) 1.4 相机采图转算子输入(CmvdImage) 2.Bitmap取图与VM对应图像格式互…...

气象白化的三种方法

【总结】cnmaps、maskout、salem的正确打开方式 - 知乎https://zhuanlan.zhihu.com/p/636252854总结了三种方式&#xff0c;比较还是安装了Salem库&#xff0c;第一次import联网下载也很顺利&#xff01;&#xff01;&#xff01;...

Azkaban3.84集群安装部署

基础环境配置 上传安装包并解压 tar -zxvf azkaban-exec-server-3.84.4.tar.gz -C /ddhome/bin/ tar -zxvf azkaban-web-server-3.84.4.tar.gz -C /ddhome/bin/ tar -zxvf azkaban-db-3.84.4.tar.gz -C /ddhome/bin/mv azkaban-exec-server-3.84.4 azkaban-exec mv azkaban-w…...

Linux 内核中的内存管理:从物理内存到虚拟内存

Linux 内核中的内存管理&#xff1a;从物理内存到虚拟内存 引言 作为一名深耕操作系统和嵌入式开发的工程师&#xff0c;我深知资源管理的重要性。在系统开发中&#xff0c;合理的资源管理可以提高系统的性能和可靠性。在 Linux 内核中&#xff0c;内存管理是一个核心组件&…...

计算机毕业设计:Python二手车市场数据分析与价格预测系统 Django框架 随机森林 可视化 数据分析 汽车 车辆 大数据 hadoop(建议收藏)✅

1、项目介绍 技术栈 Python、Django、MySQL、机器学习随机森林算法、Echarts可视化、HTML、阿里云天池数据集 功能模块 注册登录界面不同车龄平均价格柱状图分析不同车龄数量分布饼图二手车售价分布饼图不同地区二手车平均价格柱状图分析里程价格折线图分析特征值和价格相关性分…...

低代码AI开发:这些工具让AI原生应用开发效率提升10倍

低代码AI开发&#xff1a;这些工具让AI原生应用开发效率提升10倍 关键词&#xff1a;低代码开发、AI原生应用、开发效率、AutoML、拖拽式建模、企业级AI落地、工具链整合 摘要&#xff1a;传统AI开发需要精通算法、数据处理和工程实现&#xff0c;门槛高且周期长。本文将揭秘“…...

SD-WebUI Cleaner 终极指南:AI图像清理与对象移除完整教程

SD-WebUI Cleaner 终极指南&#xff1a;AI图像清理与对象移除完整教程 【免费下载链接】sd-webui-cleaner An extension for stable-diffusion-webui to remove any object. 项目地址: https://gitcode.com/gh_mirrors/sd/sd-webui-cleaner 你是否曾经想要从照片中移除不…...

反线性学习—— 不是“按顺序学完教材”,是“围绕目标把知识长出来”

反线性学习—— 不是“按顺序学完教材”&#xff0c;是“围绕目标把知识长出来”在传统的学习习惯中&#xff0c;我们往往有一种 “进度条强迫症”&#xff1a;只要书看完了、课听完了、笔记记满了&#xff0c;就觉得自己“学完了”。 但现实往往很残酷&#xff1a;当你合上书本…...

告别官方镜像!手把手教你将自编译Android系统刷入AVD(基于Android Studio 4.2+)

告别官方镜像&#xff01;手把手教你将自编译Android系统刷入AVD&#xff08;基于Android Studio 4.2&#xff09; 在Android开发领域&#xff0c;模拟器&#xff08;AVD&#xff09;一直是开发者调试和测试应用的重要工具。然而&#xff0c;大多数开发者仅限于使用Google提供的…...

【异常】设备时间戳时区偏差问题分析与解决(实际应为上午11点,但数据库存储为晚上7点)

一、问题现象 在生产环境中发现,IoT 设备上报的对话记录时间存在异常。具体表现为: 实际时间:2026年3月30日 上午 11:00 数据库存储时间:2026年3月30日 晚上 19:00 时间偏差:约 8 小时 数据库查询示例: -- 实际应为上午11点,但数据库存储为晚上7点 dialog_time: 2026-…...

ROCm零基础入门实战指南:从环境搭建到高性能计算

ROCm零基础入门实战指南&#xff1a;从环境搭建到高性能计算 【免费下载链接】ROCm AMD ROCm™ Software - GitHub Home 项目地址: https://gitcode.com/GitHub_Trending/ro/ROCm AMD ROCm&#xff08;Radeon Open Compute&#xff09;是一套开源GPU计算平台&#xff0c…...

Shell脚本新手必看:6种方法彻底解决Undefined Variable报错(附代码示例)

Shell脚本变量报错终极指南&#xff1a;从根源解决Undefined Variable问题 在Linux系统管理和自动化运维中&#xff0c;Shell脚本是不可或缺的工具。但许多初学者在编写脚本时&#xff0c;经常会遇到"Undefined Variable"这类看似简单却令人头疼的报错。这种错误不仅…...

从F1 90到62 F1 90:用Wireshark和CANoe‘解剖’一次完整的UDS 0x22数据读取会话

从F190到62F190&#xff1a;用Wireshark和CANoe解剖UDS 0x22数据读取会话 当你第一次在Wireshark中看到22服务请求和62响应报文时&#xff0c;那些十六进制字节可能就像天书一样难以理解。但正是这些看似杂乱的数据流&#xff0c;承载着现代汽车电子系统最核心的诊断信息交换。…...