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

设计模式九:组合模式(Composite Pattern)

组合模式是一种结构型设计模式,它允许我们将对象组合成树形结构来表示“整体-部分”层次关系。组合模式使得用户可以以相同的方式处理单个对象和组合对象。
在组合模式中,有两种主要类型的对象:叶子对象和组合对象。叶子对象代表树结构中的最终节点,它们没有子节点。而组合对象代表树结构中的中间节点,它们可以包含子节点。
通过使用组合模式,我们可以创建具有嵌套结构的对象,并且可以递归地处理这些对象。这种递归性质使得组合模式非常适用于处理树状数据结构,例如文件系统、组织架构等。

组合模式的一些特点:

组合模式可以帮助我们简化对树形结构的操作,并提供更灵活的方式来处理对象间的层次关系。它在许多应用领域中都有广泛的应用,特别是在图形用户界面、文件系统和组织架构等方面

  • 通过接口或抽象类定义统一的操作方法,使得客户代码可以透明地处理单个对象和组合对象。
  • 具体的叶子对象和组合对象都实现这个接口或继承这个抽象类,并实现自己特定的操作方法。
  • 组合对象可以包含其他组合对象或叶子对象,从而形成树形结构。
  • 可以在运行时动态地添加、删除或修改组合对象。
  • 客户代码可以通过递归遍历整个树状结构来执行操作。

组合模式是一种结构型设计模式,它将对象组合成树形结构以表示"部分-整体"的层次结构。该模式使得用户可以统一处理单个对象和组合对象,而无需区分它们的具体类型。

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

组合模式适用于需要处理部分-整体关系的场景,并且希望以统一的方式对单个对象和组合对象进行操作的情况。它可以简化对象结构的表示和操作,提高系统的灵活性和可扩展性

  1. 需要表示对象的部分-整体层次结构,且希望能够以统一的方式处理其中的所有对象。例如,文件系统中的文件夹和文件之间的关系,可以使用组合模式来表示并提供统一的操作接口。
  2. 希望客户端对单个对象和组合对象进行一致的操作,并且不需要关心对象的具体类型。通过组合模式,客户端可以将对组合对象的操作委托给其子对象,而无需知道具体执行的是单个对象还是整个组合。
  3. 需要对树状结构进行递归遍历,在每个节点上执行相同的操作。组合模式可简化遍历操作的实现,通过递归地遍历组合对象的每个子对象,可以方便地操作整个树状结构。
  4. 希望为对象提供嵌套复制的功能,以便在需要时可以轻松地创建对象的副本。组合模式可简化对象的复制过程,通过递归地复制组合对象的每个子对象,可以实现整个树状结构的深度复制。

组合模式的主要角色

  1. Component(组件):定义叶子节点和容器节点的抽象接口,声明了在树状结构中所有对象共有的操作方法。它可以是一个抽象类或接口,提供了默认的实现或者一些通用的操作。
  2. Leaf(叶子节点):是组合中的叶子对象,表示树状结构中的最底层节点。叶子节点没有子节点,只能执行具体的操作,不能增加或删除子节点。
  3. Composite(容器节点):是组合中的容器对象,可以包含其他的叶子节点和容器节点。容器节点实现了Component接口,并可以对其子节点进行增加、删除和遍历等操作。
  4. Client(客户端):通过Component接口与组合中的对象进行交互,可以使用统一的方式处理叶子节点和容器节点。客户端不需要知道具体的对象类型,只需要通过Component接口来访问和操作对象。
    在组合模式中,容器节点和叶子节点都可以作为树状结构的节点,但它们之间的职责是不同的。叶子节点负责执行具体的操作,而容器节点负责管理子节点并提供一些与子节点相关的操作。通过这种方式,组合模式能够统一处理单个对象和组合对象,使得整个树状结构能够以一致的方式进行操作和管理。

java代码实例

import java.util.ArrayList;
import java.util.List;// 组件接口
interface Component {void operation();
}// 叶子节点
class Leaf implements Component {private String name;public Leaf(String name) {this.name = name;}@Overridepublic void operation() {System.out.println("执行叶子节点:" + name);}
}// 容器节点
class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void remove(Component component) {children.remove(component);}@Overridepublic void operation() {System.out.println("执行容器节点");for (Component component : children) {component.operation();}}
}public class Main {public static void main(String[] args) {// 创建树状结构Composite root = new Composite();Composite branch1 = new Composite();branch1.add(new Leaf("叶子节点1"));branch1.add(new Leaf("叶子节点2"));Composite branch2 = new Composite();branch2.add(new Leaf("叶子节点3"));branch2.add(new Leaf("叶子节点4"));root.add(branch1);root.add(branch2);// 执行操作root.operation();}
}

在上面的示例中,我们首先定义了Component接口作为组件的抽象。然后,实现了叶子节点Leaf和容器节点Composite。叶子节点只能执行具体的操作,而容器节点可以管理子节点并执行一些操作。
在Composite类中,通过List来管理子节点,并提供了添加和删除子节点的方法。在operation方法中,遍历所有子节点并执行它们的操作。

组合模式的优缺点

组合模式的优点:

  1. 简化客户端代码:组合模式通过统一叶子节点和容器节点的接口,使得客户端可以统一对待它们。客户端不需要知道具体是处理单个对象还是某个组合对象,从而简化了客户端的代码。
  2. 灵活性和可扩展性:由于叶子节点和容器节点共享相同的接口,因此可以很容易地添加新的叶子节点或容器节点,从而增加系统的灵活性和可扩展性。
  3. 递归结构:组合模式通过递归结构实现了对象间的层次关系,这使得我们可以使用递归算法在整个组合结构中进行操作。

组合模式的缺点:

  1. 可能导致设计过度复杂:当组合结构非常复杂时,可能会导致实现和理解变得困难。过度使用组合模式可能会导致系统的复杂性增加。
  2. 不适用于每个场景:组合模式适用于树状结构中的组件,但并不是所有的场景都符合这种结构。如果场景不适合树状结构,使用组合模式可能会引入不必要的复杂性。

总之,组合模式适用于需要处理树状结构并且希望统一对待单个对象和组合对象的场景。它能够简化客户端代码,提供灵活性和可扩展性,但需要注意不要过度复杂化设计,并且仔细考虑是否适用于特定的场景。

相关文章:

设计模式九:组合模式(Composite Pattern)

组合模式是一种结构型设计模式&#xff0c;它允许我们将对象组合成树形结构来表示“整体-部分”层次关系。组合模式使得用户可以以相同的方式处理单个对象和组合对象。 在组合模式中&#xff0c;有两种主要类型的对象&#xff1a;叶子对象和组合对象。叶子对象代表树结构中的最…...

【COlor传感器】通过扰动调制光传感实现智能光传输的占用分布估计研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

微服务系列<3>---微服务的调用组件 rpc 远程调用

什么是rpc调用,让我们调用远程方法就像调用本地方法一样 这就属于rpc调用 rpc是针对于本地来说的 调用远程方法根调用本地方法一样 如果能达到这种效果 就是rpc调用如果达到一种效果 调用远程和调用本地一样 他就是一种rpc框架2个微服务 之间发的调用 我们之前通过ribbon的方式…...

P1558 色板游戏

题目链接 题目要求实现区间覆盖修改以及区间数量查询&#xff0c;不难想到为线段树&#xff0c;而需要维护什么值来得到不同数的数量很难想&#xff0c;但是我们注意到颜色的数量最多只有30种&#xff0c;所以对于每一种颜色在一个区间中是否存在&#xff0c;我们可以使用线段树…...

大数据概论

1、大数据概念 大数据(Big Data): 指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产 大数据主要解决&#xff0c;海量数据的采集、存储和分…...

数据库访问中间件--springdata-jpa的基本使用

二、单表SQL操作-使用关键字拼凑方法 回顾 public interface UserRepository extends JpaRepository<User,Integer> {User findByUsernameLike(String username); }GetMapping("/user/username/{username}")public Object findUserByUsername(PathVariable S…...

c++游戏制作指南(二):制作一个炫酷的启动界面(c++绘图)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到静渊隐者的csdn博文&#xff0c;本文是c游戏制作指南的一部&#x1f35f; &#x1f355;更多文章请点击下方链接&#x1f355; &#x1f368; c游戏制作指南&#x1f3…...

spring.config.location 手动指定配置文件文件

–spring.config.locationD:\javaproject\bangsun\ds-admin\ds-oper-mgr\src\main\resources\application.yml...

【uniapp 使用ECharts】

Uniapp可以使用ECharts进行数据可视化&#xff0c;需要按照以下步骤进行操作&#xff1a; 1. 安装ECharts插件 可以使用npm安装echarts插件&#xff0c;命令如下&#xff1a; npm install echarts --save2. 引入ECharts插件 在需要使用ECharts的页面中引入ECharts插件&…...

数据结构--线性表2-2

目录 一、线性表例题&#xff1a; 二、分配动态内存&#xff1a; 1.动态创建一个空顺序表的算法&#xff1a; 2.动态顺序表的插入算法&#xff1a; 3.动态顺序表的删除 三、线性表的链式表示和实现 例题1&#xff1a;创建链表并插入26个字母 例题2&#xff1a;在链表中取…...

利用openTCS实现车辆调度系统(一)系统介绍

系统介绍 openTCS简介 官方的回答&#xff1a; openTCS&#xff08;开放式运输控制系统的缩写&#xff09;是一种免费的控制系统软件&#xff0c;用于协调自动导引车&#xff08;AGV&#xff09;和移动机器人车队&#xff0c;例如在生产工厂中。 通常应该可以控制任何具有通信…...

销存管理系统ssm进销存仓库销售java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 销存管理系统ssm 系统有1权限&#xff1a;管理员 二…...

【Axure教程】移动端二级滑动选择器

今天教大家制作移动端二级滑动选择器的原型模板&#xff0c;该原型已全国一二级省市选择器为案例&#xff0c;因为该原型用中继器做的&#xff0c;所以制作完成之后使用也很方便&#xff0c;只需修改中继器表格里的内容即可 一、效果展示 1. 拖动选择 2. 快捷选择 【原型预览…...

PHP操作solr

1&#xff0c;php下载solr(索尔)扩展&#xff0c;phpinfo需要支持solr扩展. 2&#xff0c;安装 Solr。Solr 要求您的系统上有 Java。java –version&#xff0c;Java 的版本大于 1.6 3&#xff0c;下载solr,并安装 D:\solr。 开启solr命令&#xff1a;solr start 关闭solr命令:…...

leetcode 46. Permutations(排列)

返回数组nums中数字的所有可能的排列组合。 思路&#xff1a; 排列组合这种一般会想到DFS。 这个排列中每个数字只能用一次&#xff0c; 可用如下DFS流程 stack.push(num); dfs(nums, num); stack.pop();退出条件&#xff1a; 当stack的size和nums数组一样时&#xff0c;说…...

5、二叉树

二叉树遍历 递归序 public static void f(Node head) {if (head == null) {return;}f(head.left);f(head.right); }前中后遍历_递归 public static void preOrderRecur(Node head) {if (head == null) {return;}System.out.print(head.value + " ");preOrderRecur…...

Doris比MySQL快的原因

简介 在数据存储和数据分析领域&#xff0c;MySQL和Doris是比较流行的数据库管理系统的代表。 在如今的大数据时代&#xff0c;数据量和数据分析的速度是很重要的。 在数据分析和数据处理中&#xff0c;Doris比MySQL快&#xff0c;这个问题一直是许多人关心的问题。 Doris的数…...

Prometheus + Grafana安装

Prometheus是一款基于时序数据库的开源监控告警系统&#xff0c;非常适合Kubernetes集群的监控。Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做…...

二十三种设计模式第二十一篇--解释器模式

解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;它用于定义一种语言的语法结构和解释器&#xff0c;使得可以解释并执行特定的语法规则。该模式可以将复杂的语言表达式分解为更小的语法单元&#xff0c;并定义其解释过程。 解释器模式的…...

PHP8的数据类型转换-PHP8知识详解

什么是数据类型转换&#xff1f; 答&#xff1a;数据从一个类型转换成另外一个类型&#xff0c;就是数据类型转换。 在PHP8中&#xff0c;变量的类型就是由赋值决定的&#xff0c;也就是说&#xff0c;如果 string 赋值给 $var&#xff0c;然后 $var 的类型就是 string。之后…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...

嵌入式常见 CPU 架构

架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集&#xff0c;单周期执行&#xff1b;低功耗、CIP 独立外设&#xff1b;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel&#xff08;原始…...