设计模式九:组合模式(Composite Pattern)
组合模式是一种结构型设计模式,它允许我们将对象组合成树形结构来表示“整体-部分”层次关系。组合模式使得用户可以以相同的方式处理单个对象和组合对象。
在组合模式中,有两种主要类型的对象:叶子对象和组合对象。叶子对象代表树结构中的最终节点,它们没有子节点。而组合对象代表树结构中的中间节点,它们可以包含子节点。
通过使用组合模式,我们可以创建具有嵌套结构的对象,并且可以递归地处理这些对象。这种递归性质使得组合模式非常适用于处理树状数据结构,例如文件系统、组织架构等。
组合模式的一些特点:
组合模式可以帮助我们简化对树形结构的操作,并提供更灵活的方式来处理对象间的层次关系。它在许多应用领域中都有广泛的应用,特别是在图形用户界面、文件系统和组织架构等方面
- 通过接口或抽象类定义统一的操作方法,使得客户代码可以透明地处理单个对象和组合对象。
- 具体的叶子对象和组合对象都实现这个接口或继承这个抽象类,并实现自己特定的操作方法。
- 组合对象可以包含其他组合对象或叶子对象,从而形成树形结构。
- 可以在运行时动态地添加、删除或修改组合对象。
- 客户代码可以通过递归遍历整个树状结构来执行操作。
组合模式是一种结构型设计模式,它将对象组合成树形结构以表示"部分-整体"的层次结构。该模式使得用户可以统一处理单个对象和组合对象,而无需区分它们的具体类型。
组合模式适用于以下场景:
组合模式适用于需要处理部分-整体关系的场景,并且希望以统一的方式对单个对象和组合对象进行操作的情况。它可以简化对象结构的表示和操作,提高系统的灵活性和可扩展性
- 需要表示对象的部分-整体层次结构,且希望能够以统一的方式处理其中的所有对象。例如,文件系统中的文件夹和文件之间的关系,可以使用组合模式来表示并提供统一的操作接口。
- 希望客户端对单个对象和组合对象进行一致的操作,并且不需要关心对象的具体类型。通过组合模式,客户端可以将对组合对象的操作委托给其子对象,而无需知道具体执行的是单个对象还是整个组合。
- 需要对树状结构进行递归遍历,在每个节点上执行相同的操作。组合模式可简化遍历操作的实现,通过递归地遍历组合对象的每个子对象,可以方便地操作整个树状结构。
- 希望为对象提供嵌套复制的功能,以便在需要时可以轻松地创建对象的副本。组合模式可简化对象的复制过程,通过递归地复制组合对象的每个子对象,可以实现整个树状结构的深度复制。
组合模式的主要角色
- Component(组件):定义叶子节点和容器节点的抽象接口,声明了在树状结构中所有对象共有的操作方法。它可以是一个抽象类或接口,提供了默认的实现或者一些通用的操作。
- Leaf(叶子节点):是组合中的叶子对象,表示树状结构中的最底层节点。叶子节点没有子节点,只能执行具体的操作,不能增加或删除子节点。
- Composite(容器节点):是组合中的容器对象,可以包含其他的叶子节点和容器节点。容器节点实现了Component接口,并可以对其子节点进行增加、删除和遍历等操作。
- 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方法中,遍历所有子节点并执行它们的操作。
组合模式的优缺点
组合模式的优点:
- 简化客户端代码:组合模式通过统一叶子节点和容器节点的接口,使得客户端可以统一对待它们。客户端不需要知道具体是处理单个对象还是某个组合对象,从而简化了客户端的代码。
- 灵活性和可扩展性:由于叶子节点和容器节点共享相同的接口,因此可以很容易地添加新的叶子节点或容器节点,从而增加系统的灵活性和可扩展性。
- 递归结构:组合模式通过递归结构实现了对象间的层次关系,这使得我们可以使用递归算法在整个组合结构中进行操作。
组合模式的缺点:
- 可能导致设计过度复杂:当组合结构非常复杂时,可能会导致实现和理解变得困难。过度使用组合模式可能会导致系统的复杂性增加。
- 不适用于每个场景:组合模式适用于树状结构中的组件,但并不是所有的场景都符合这种结构。如果场景不适合树状结构,使用组合模式可能会引入不必要的复杂性。
总之,组合模式适用于需要处理树状结构并且希望统一对待单个对象和组合对象的场景。它能够简化客户端代码,提供灵活性和可扩展性,但需要注意不要过度复杂化设计,并且仔细考虑是否适用于特定的场景。
相关文章:
设计模式九:组合模式(Composite Pattern)
组合模式是一种结构型设计模式,它允许我们将对象组合成树形结构来表示“整体-部分”层次关系。组合模式使得用户可以以相同的方式处理单个对象和组合对象。 在组合模式中,有两种主要类型的对象:叶子对象和组合对象。叶子对象代表树结构中的最…...
【COlor传感器】通过扰动调制光传感实现智能光传输的占用分布估计研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
微服务系列<3>---微服务的调用组件 rpc 远程调用
什么是rpc调用,让我们调用远程方法就像调用本地方法一样 这就属于rpc调用 rpc是针对于本地来说的 调用远程方法根调用本地方法一样 如果能达到这种效果 就是rpc调用如果达到一种效果 调用远程和调用本地一样 他就是一种rpc框架2个微服务 之间发的调用 我们之前通过ribbon的方式…...
P1558 色板游戏
题目链接 题目要求实现区间覆盖修改以及区间数量查询,不难想到为线段树,而需要维护什么值来得到不同数的数量很难想,但是我们注意到颜色的数量最多只有30种,所以对于每一种颜色在一个区间中是否存在,我们可以使用线段树…...
大数据概论
1、大数据概念 大数据(Big Data): 指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产 大数据主要解决,海量数据的采集、存储和分…...
数据库访问中间件--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++绘图)
🍿*★,*:.☆( ̄▽ ̄)/$:*.★* 🍿 🍟欢迎来到静渊隐者的csdn博文,本文是c游戏制作指南的一部🍟 🍕更多文章请点击下方链接🍕 🍨 c游戏制作指南dz…...
spring.config.location 手动指定配置文件文件
–spring.config.locationD:\javaproject\bangsun\ds-admin\ds-oper-mgr\src\main\resources\application.yml...
【uniapp 使用ECharts】
Uniapp可以使用ECharts进行数据可视化,需要按照以下步骤进行操作: 1. 安装ECharts插件 可以使用npm安装echarts插件,命令如下: npm install echarts --save2. 引入ECharts插件 在需要使用ECharts的页面中引入ECharts插件&…...
数据结构--线性表2-2
目录 一、线性表例题: 二、分配动态内存: 1.动态创建一个空顺序表的算法: 2.动态顺序表的插入算法: 3.动态顺序表的删除 三、线性表的链式表示和实现 例题1:创建链表并插入26个字母 例题2:在链表中取…...
利用openTCS实现车辆调度系统(一)系统介绍
系统介绍 openTCS简介 官方的回答: openTCS(开放式运输控制系统的缩写)是一种免费的控制系统软件,用于协调自动导引车(AGV)和移动机器人车队,例如在生产工厂中。 通常应该可以控制任何具有通信…...
销存管理系统ssm进销存仓库销售java jsp源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 销存管理系统ssm 系统有1权限:管理员 二…...
【Axure教程】移动端二级滑动选择器
今天教大家制作移动端二级滑动选择器的原型模板,该原型已全国一二级省市选择器为案例,因为该原型用中继器做的,所以制作完成之后使用也很方便,只需修改中继器表格里的内容即可 一、效果展示 1. 拖动选择 2. 快捷选择 【原型预览…...
PHP操作solr
1,php下载solr(索尔)扩展,phpinfo需要支持solr扩展. 2,安装 Solr。Solr 要求您的系统上有 Java。java –version,Java 的版本大于 1.6 3,下载solr,并安装 D:\solr。 开启solr命令:solr start 关闭solr命令:…...
leetcode 46. Permutations(排列)
返回数组nums中数字的所有可能的排列组合。 思路: 排列组合这种一般会想到DFS。 这个排列中每个数字只能用一次, 可用如下DFS流程 stack.push(num); dfs(nums, num); stack.pop();退出条件: 当stack的size和nums数组一样时,说…...
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快的原因
简介 在数据存储和数据分析领域,MySQL和Doris是比较流行的数据库管理系统的代表。 在如今的大数据时代,数据量和数据分析的速度是很重要的。 在数据分析和数据处理中,Doris比MySQL快,这个问题一直是许多人关心的问题。 Doris的数…...
Prometheus + Grafana安装
Prometheus是一款基于时序数据库的开源监控告警系统,非常适合Kubernetes集群的监控。Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态,任意组件只要提供对应的HTTP接口就可以接入监控。不需要任何SDK或者其他的集成过程。这样做非常适合做…...
二十三种设计模式第二十一篇--解释器模式
解释器模式(Interpreter Pattern)是一种行为设计模式,它用于定义一种语言的语法结构和解释器,使得可以解释并执行特定的语法规则。该模式可以将复杂的语言表达式分解为更小的语法单元,并定义其解释过程。 解释器模式的…...
PHP8的数据类型转换-PHP8知识详解
什么是数据类型转换? 答:数据从一个类型转换成另外一个类型,就是数据类型转换。 在PHP8中,变量的类型就是由赋值决定的,也就是说,如果 string 赋值给 $var,然后 $var 的类型就是 string。之后…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
