当前位置: 首页 > 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。之后…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

对象回调初步研究

_OBJECT_TYPE结构分析 在介绍什么是对象回调前&#xff0c;首先要熟悉下结构 以我们上篇线程回调介绍过的导出的PsProcessType 结构为例&#xff0c;用_OBJECT_TYPE这个结构来解析它&#xff0c;0x80处就是今天要介绍的回调链表&#xff0c;但是先不着急&#xff0c;先把目光…...

【Qt】控件 QWidget

控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态&#xff1a;enabled几何&#xff1a;geometrywindows frame 窗口框架的影响 窗口标题&#xff1a;windowTitle窗口图标&#xff1a;windowIconqrc 机制 窗口不透明度&#xff1a;windowOpacity光标&#xff1a;cursor…...

Pandas 可视化集成:数据科学家的高效绘图指南

为什么选择 Pandas 进行数据可视化&#xff1f; 在数据科学和分析领域&#xff0c;可视化是理解数据、发现模式和传达见解的关键步骤。Python 生态系统提供了多种可视化工具&#xff0c;如 Matplotlib、Seaborn、Plotly 等&#xff0c;但 Pandas 内置的可视化功能因其与数据结…...