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

Python 如何实现组合(Composite)设计模式?什么是组合设计模式?

什么是组合(Composite)设计模式?

组合(Composite)设计模式是一种结构型设计模式,它允许客户端使用单一对象和组合对象(对象的组合形成树形结构)同样的方式处理。这样,客户端无需关心处理的是单一对象还是对象组合,从而使得客户端代码更简单、更一致。

在这里插入图片描述

主要角色:

  1. 组件(Component): 定义了组合中所有对象的通用接口,可以是抽象类或接口,声明了包含子组件的操作。

  2. 叶子节点(Leaf): 是组合中的叶子对象,没有子节点,实现了组件接口。

  3. 复合节点(Composite): 是组合中的复合对象,包含子节点,实现了组件接口。复合节点的操作通常会委托给其子节点。

工作流程:

  1. 组件接口(Component): 定义了组合中所有对象的通用接口,包括包含子组件的操作(例如,addremoveget_children等)以及一些操作,可以是抽象类或接口。

  2. 叶子节点(Leaf): 是组合中的叶子对象,实现了组件接口。它没有子节点,其操作可能是具体的业务逻辑。

  3. 复合节点(Composite): 是组合中的复合对象,实现了组件接口。它包含子节点,其操作通常会委托给其子节点。复合节点可以有多个子节点,包括叶子节点和其他复合节点。

Python 示例代码(一):

下面是一个使用组合模式的示例,表示一个组织结构:

from abc import ABC, abstractmethod# 组件接口
class Component(ABC):@abstractmethoddef operation(self):pass# 叶子节点
class Leaf(Component):def operation(self):print("Performing leaf operation.")# 复合节点
class Composite(Component):def __init__(self):self.children = []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def operation(self):print("Performing composite operation:")for child in self.children:child.operation()# 客户端
leaf1 = Leaf()
leaf2 = Leaf()
composite = Composite()
composite.add(leaf1)
composite.add(leaf2)client = Composite()
client.add(composite)
client.add(Leaf())client.operation()

在这个示例中,Component 是组件接口,Leaf 是叶子节点,Composite 是复合节点。客户端可以将叶子节点和复合节点一视同仁,调用它们的 operation 方法,而无需关心它们的具体类型。这样,组合模式使得处理单一对象和组合对象更加统一。

Python 示例代码(二)

假设我们正在开发一个文件系统的模块,需要设计一个类来表示目录和文件,并使用组合模式。目录可以包含文件和其他目录,从而形成一个树状结构。

from abc import ABC, abstractmethod# 组件接口
class FileSystemComponent(ABC):@abstractmethoddef display(self):pass# 叶子节点 - 文件
class File(FileSystemComponent):def __init__(self, name):self.name = namedef display(self):print(f"File: {self.name}")# 复合节点 - 目录
class Directory(FileSystemComponent):def __init__(self, name):self.name = nameself.children = []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def display(self):print(f"Directory: {self.name}")for child in self.children:child.display()# 客户端
file1 = File("document.txt")
file2 = File("image.jpg")subdirectory = Directory("Subdirectory")
subdirectory.add(File("subfile1.txt"))
subdirectory.add(File("subfile2.txt"))root = Directory("Root")
root.add(file1)
root.add(file2)
root.add(subdirectory)# 打印整个文件系统
root.display()

在这个示例中,FileSystemComponent 是组件接口,File 是叶子节点,表示文件,Directory 是复合节点,表示目录。目录可以包含文件和其他目录,形成一个树状结构。客户端可以调用 display 方法来展示整个文件系统的结构,而无需关心是文件还是目录。这种设计方式使得文件系统的表示更加灵活,能够方便地处理目录和文件的组合关系。

使用组合设计模式,需要注意哪些地方?

在实现组合设计模式时,有一些需要注意的地方,以确保模式的有效实施和系统的可维护性:

  1. 一致的接口: 确保所有的组件(包括叶子节点和复合节点)都实现了相同的接口,这样客户端可以一致地对待它们。

  2. 添加和移除操作: 对于复合节点,实现添加和移除子组件的操作。确保这些操作能够正确地处理子组件的添加和移除,并且不会破坏整个树结构。

  3. 透明性和安全性: 在设计时需要考虑透明组合和安全组合两种方式。透明组合中,所有组件都有相同的接口,但可能存在不适用的方法。安全组合中,不同类型的组件可能有不同的接口,需要客户端进行类型检查。

  4. 遍历方式: 定义遍历组合结构的方式。通常,可以使用递归方式遍历整个树状结构,确保每个节点都被正确地访问。

  5. 共享叶子节点: 如果有多个复合节点需要共享相同的叶子节点,确保这些共享的叶子节点不会因为一个复合节点的修改而影响其他节点。

  6. 处理不支持的操作: 在叶子节点中可能存在一些复合节点不支持的操作,确保对这些操作进行适当的处理,例如抛出异常或返回默认值。

  7. 内存消耗: 组合模式可能导致一些额外的内存开销,特别是在树结构较大时。需要谨慎设计,考虑使用享元模式等方式减少内存消耗。

  8. 设计树的深度: 考虑组合树的深度。如果树的深度很大,可能需要使用迭代器模式等方式来遍历树而不是依赖递归。

  9. 线程安全性: 如果组合结构会在多线程环境中使用,确保组合模式的实现是线程安全的或采取适当的同步措施。

  10. 具体组件类型: 在设计组件时,考虑可能的具体组件类型。有时可以使用接口继承,有时可能需要使用抽象类。

通过考虑这些方面,可以确保实现的组合模式在系统中稳健且易于维护。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

相关文章:

Python 如何实现组合(Composite)设计模式?什么是组合设计模式?

什么是组合(Composite)设计模式? 组合(Composite)设计模式是一种结构型设计模式,它允许客户端使用单一对象和组合对象(对象的组合形成树形结构)同样的方式处理。这样,客…...

编辑器vim和编译器gcc/g++

目录 一、编辑器vim 1、概念 2、基本操作 1、进入vim 2、模式切换 3、命令行模式 4、插入模式 5、底行模式 6、vim 的配置 二、编译器gcc/g 1、概念 2、背景知识 3、gcc/g中的编译链接 1、预处理 2、编译 3、汇编 4、链接 4、函数库 1、静态库 2、动态库 一…...

linux 系统下文本编辑常用的命令

一、是什么 Vim是从 vi 发展出来的一个文本编辑器,代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。 简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方 而…...

3D Gaussian Splatting文件的压缩【3D高斯泼溅】

在上一篇文章中,我开始研究高斯泼溅(3DGS:3D Gaussian Splatting)。 它的问题之一是数据集并不小。 渲染图看起来不错。 但“自行车”、“卡车”、“花园”数据集分别是一个 1.42GB、0.59GB、1.35GB 的 PLY 文件。 它们几乎按原样…...

Spring Boot 整合xxl-job实现分布式定时任务

xxl-job介绍 XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 xxl是xxl-job的开发者大众点评的许雪里名称的拼音开头。 设计思想 将调度行为抽象形成“调度…...

16.最接近的三数之和

​​题目来源: leetcode题目,网址:16. 最接近的三数之和 - 力扣(LeetCode) 解题思路: 对数组排序后,枚举第一个值,利用双指针在第一个值固定时的第二三个值。 解题代码&#xff1a…...

php 插入排序算法实现

插入排序是一种简单直观的排序算法,它的基本思想是将一个数据序列分为有序区和无序区,每次从无序区选择一个元素插入到有序区的合适位置,直到整个序列有序为止 5, 3, 8, 2, 0, 1 HP中可以使用以下代码实现插入排序算法: functi…...

import gradio时出现SyntaxError: future feature annotations is not defined解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

视频封装格式

FLV(Flash Video) FLV封装格式 Tag Data分为Audio,Video,Script三种 TS(Transport Stream)传输流 TS文件分为三层,(倒叙更好理解) TS层:在PES层基础上加入…...

vue+iView实现下载zip文件导出多个excel表格

1&#xff0c;需求&#xff1a;在vue项目中&#xff0c;实现分月份导出多个Excel表格。 点击导出&#xff0c;下载zip文件&#xff0c;解压出多张表数据。 2&#xff0c;关键代码&#xff1a; <Button class"export button-style button-space" click"ex…...

Rust编程中的共享状态并发执行

1.共享状态并发 虽然消息传递是一个很好的处理并发的方式&#xff0c;但并不是唯一一个。另一种方式是让多个线程拥有相同的共享数据。在学习Go语言编程过程中大家应该听到过一句口号:"不要通过共享内存来通讯"。 在某种程度上&#xff0c;任何编程语言中的信道都类…...

python语法之数据类型

在python编程中&#xff0c;数据类型是一个重要的概念。 变量可以存储不同类型的数据&#xff0c;不同的类型可以做不同的事情。 Python在这些类别中默认内置了以下数据类型: 文本类型&#xff1a;str数值类型&#xff1a;int, float, complex序列类型&#xff1a;list, tup…...

Skybox天空盒子的更换教程_unity基础开发教程

Skybox天空盒子的更换 Skybox的下载与导入更换SkyboxSkybox属性自定义 Skybox的下载与导入 打开资源商店 搜索FREE Skybox 这里是我使用的是这一款资源&#xff0c;点击添加至我的资源 打开包管理器Package Manager Packages选择My Assets 搜索Sky 选择刚刚添加的天空盒子 点…...

Android模拟器的linux内核源码的下载

文章目录 Android模拟器的linux内核源码的下载 Android模拟器的linux内核源码的下载 git clone https://aosp.tuna.tsinghua.edu.cn/android/kernel/goldfish.git自己新建一个文件夹存放内核代码&#xff0c;命名随意。 切换一下分支就有东西了 切换到下面这个分支...

Vue中methods实现原理

目录 前言 回调函数中的this指向问题 vue实例访问methods methods实现原理 前言 vue实例对象为什么可以访问methods中的函数方法&#xff1f;methods的实现原理是什么&#xff1f; 回调函数中的this指向问题 在解答前言中的问题前&#xff0c;需要了解一下回调函数中的th…...

维基百科是非营利性机构 词条内容具有中立性、准确性、可靠性

维基百科对一些企业很有神秘性&#xff0c;自行操作很多次也没有成功建立维基百科&#xff0c;这一定是没有按照维基百科的规则和流程去操作。小马识途营销顾问提醒企业&#xff0c;维基百科是一种基于协作的在线百科全书&#xff0c;由维基媒体基金会运营。维基百科的创建流程…...

C/C++轻量级并发TCP服务器框架Zinx-框架开发002: 定义通道抽象类

文章目录 2 类图设计3 时序图数据输入处理&#xff1a;输出数据处理总流程 4 主要实现的功能4.1 kernel类&#xff1a;基于epoll调度所有通道4.2 通道抽象类&#xff1a;4.3 标准输入通道子类4.4 标准输出通道子类4.5 kernel和通道类的调用 5 代码设计5.1 框架头文件5.2 框架实…...

bin、hex、ELF文件格式上的区别

bin, hex, 和 ELF 是三种不同的文件格式&#xff0c;主要用于表示和存储二进制数据和程序代码。它们各自有其用途、特点和格式&#xff1a; bin (Binary) 文件: 通常表示纯二进制格式的文件。它不包含任何元数据或文件结构&#xff0c;只是简单地按照字节顺序存储数据。这种文件…...

《QT从基础到进阶·二十六》绘制多个图形项(QGraphicsRectItem,QGraphicsLineItem,QGraphicsPolygonItem)

这个demo用QT实现了对多个图形项的绘制&#xff0c;包括矩形的绘制&#xff0c;直线的绘制和多边形的绘制&#xff0c;是之前一章中绘制矩形的增强版&#xff0c;之前一章节关于矩形的绘制可以参考&#xff1a;《QT从基础到进阶十五》用鼠标绘制矩形&#xff08;QGraphicsView、…...

【分布式】CAP理论详解

一、CAP理论概述 在分布式系统中&#xff0c;CAP是指一组原则&#xff0c;它们描述了在网络分区&#xff08;Partition&#xff09;时&#xff0c;分布式系统能够提供的保证。CAP代表Consistency&#xff08;一致性&#xff09;、Availability&#xff08;可用性&#xff09;和…...

AI歌姬,C位出道,基于PaddleHub/Diffsinger实现音频歌声合成操作(Python3.10)

懂乐理的音乐专业人士可以通过写乐谱并通过乐器演奏来展示他们的音乐创意和构思&#xff0c;但不识谱的素人如果也想跨界玩儿音乐&#xff0c;那么门槛儿就有点高了。但随着人工智能技术的快速迭代&#xff0c;现在任何一个人都可以成为“创作型歌手”&#xff0c;即自主创作并…...

ZooKeeper基本知识

1.什么是ZooKeeper ZooKeeper是一个开源的分布式协调服务&#xff0c;它提供了一个高性能、高可靠的分布式协调基础&#xff0c;用于构建分布式系统。 具体来说&#xff0c;ZooKeeper通常用于以下几个方面&#xff1a; 配置管理&#xff1a;分布式系统通常需要集中管理配置信…...

leetcode:138. 随机链表的复制

一、题目&#xff1a; 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a; struct Node* copyRandomList(struct Node* head) 二、思路 本题是给出一个单链表&#xff0c;单链表的每个结点还额外有一个随机指针&#xff0c;随机指向其他结点&am…...

SpringBoot 全局异常之参数校验(1)

文章目录 前言背景依赖校验类型@NotBlank、@NotNull和@NotEmpty的区别@Valid和@Validated区别异常处理方式一 @RequestParam全局异常处理(ConstraintViolationException)请求示例方式二 @RequestBody(推荐)全局异常处理(MethodArgumentNotValidException)请求示例方式三(…...

QT windows与linux之间sokcet通信中文乱码问题解决方法

QT windows与linux之间sokcet通信中文乱码问题解决方法 linux发送与接收都转码utf-8: tcpClient ->write( send_msg.toUtf8());//解决乱码&#xff0c;发送转码 接收&#xff1a; QByteArray buffer tcpClient->readAll(); if(!buffer.isEmpty()) { // ui->plain…...

Java实现DXF文件转换成PDF

代码实现 public static void dxfToPdf(){// 加载DXF文件String inputFile "input.dxf";CadImage cadImage (CadImage) Image.load(inputFile);// 设置PDF输出选项PdfOptions pdfOptions new PdfOptions();pdfOptions.setPageWidth(200);pdfOptions.setPageHeigh…...

揭秘Vue中的nextTick:异步更新队列背后的技术原理大揭秘!

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、N…...

PHP使用文件缓存实现html静态化

<?php // 动态生成的内容 $content "<html><body><h1>time:".date("Y-m-d H:i:s")."</h1></body></html>"; // 静态文件保存路径和文件名 $staticFilePath "file.html"; if(file_exists($s…...

A Gentle Introduction to Graph Neural Networks

A Gentle Introduction to Graph Neural Networks----《图神经网络入门》 图神经网络信息传递积累 图在我们身边随处可见&#xff0c;现实世界中的物体通常是根据它们与其他事物的联系来定义的。一组物体以及它们之间的联系可以很自然地用图来表示。十多年来&#xff0c;研究人…...

详解[ZJCTF 2019]NiZhuanSiWei 1(PHP两种伪协议、PHP反序列化漏洞、PHP强比较)还有那道题有这么经典?

题目环境&#xff1a; <?php $text $_GET["text"]; $file $_GET["file"]; $password $_GET["password"]; if(isset($text)&&(file_get_contents($text,r)"welcome to the zjctf")){echo "<br><h1>&…...