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

十、组合模式

组合模式(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);}@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)
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 计算机毕业设计选题推荐-自驾游攻略管理系统-Java/Python项目实战
  • 让PPT动起来:用python-pptx轻松添加动画效果
  • TwinCAT3 实时核中ADS实现C++ server、clinet数据传输
  • 车载以太网之SOME/IP
  • 【达梦数据库】误删数据库目录问题复现解决方式
  • JDK 8 新增特性:Lambda 表达式
  • 亚信安全出席第五届国际反病毒大会 探究AI现代网络勒索治理
  • 骨传导耳机哪个品牌好用?精选五大高能骨传导耳机分享!
  • Learn OpenGL In Qt之着色器
  • 深度学习算法:现代人工智能的核心驱动
  • STL集合
  • 如何远程实时监控员工的电脑屏幕?远程桌面监控的五个可实现方法分享
  • soup.find(‘div‘)获取的数据长度为3,为什么1和3都是空的?
  • 研1日记8
  • ZAB协议(算法)
  • 【附node操作实例】redis简明入门系列—字符串类型
  • export和import的用法总结
  • Laravel5.4 Queues队列学习
  • Python进阶细节
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Webpack入门之遇到的那些坑,系列示例Demo
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 从tcpdump抓包看TCP/IP协议
  • 前端面试总结(at, md)
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #单片机(TB6600驱动42步进电机)
  • $nextTick的使用场景介绍
  • (42)STM32——LCD显示屏实验笔记
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (十二)Flink Table API
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • (一)u-boot-nand.bin的下载
  • .“空心村”成因分析及解决对策122344
  • .NET CLR Hosting 简介
  • .NET 解决重复提交问题
  • .NET学习教程二——.net基础定义+VS常用设置
  • /usr/bin/env: node: No such file or directory
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @Autowired和@Resource装配
  • @kafkalistener消费不到消息_消息队列对战之RabbitMq 大战 kafka
  • @ModelAttribute 注解
  • [Algorithm][动态规划][简单多状态DP问题][按摩师][打家劫舍Ⅱ][删除并获得点数][粉刷房子]详细讲解
  • [Android 13]Input系列--获取触摸窗口
  • [android学习笔记]学习jni编程
  • [AR]Vumark(下一代条形码)
  • [C++]: 模板进阶
  • [CDOJ 838]母仪天下 【线段树手速练习 15分钟内敲完算合格】
  • [ERROR]-Error: failure: repodata/filelists.xml.gz from addons: [Errno 256] No more mirrors to try.