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

设计模式--组合模式

组合模式(Composite Pattern)详解

组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

适用场景

  • 需要表示对象的部分-整体层次结构时:比如公司组织结构,文件系统等。
  • 希望用户忽略组合对象与单个对象的不同:用户将统一地使用组合结构中的所有对象。

结构

组合模式包含以下角色:

  1. Component(组件):定义了叶子和容器的共同接口或抽象类。
  2. Leaf(叶子):叶子节点,没有子节点的对象。
  3. Composite(容器):容器节点,包含子节点的对象。

代码实现

组件接口

首先,定义一个组件接口 Component,它定义了所有叶子和容器的公共操作:

import java.util.ArrayList;
import java.util.List;// Component
interface Component {void showDetails();
}

 

叶子节点

叶子节点是实现了 Component 接口的类,没有子节点:

// Leaf
class Employee implements Component {private String name;private String position;public Employee(String name, String position) {this.name = name;this.position = position;}@Overridepublic void showDetails() {System.out.println(name + " works as " + position);}
}
容器节点

容器节点是实现了 Component 接口的类,包含子节点:

// Composite
class Department implements Component {private String name;private List<Component> employees = new ArrayList<>();public Department(String name) {this.name = name;}public void addEmployee(Component employee) {employees.add(employee);}public void removeEmployee(Component employee) {employees.remove(employee);}@Overridepublic void showDetails() {System.out.println("Department: " + name);for (Component employee : employees) {employee.showDetails();}}
}
客户端代码

客户端代码使用组合模式来创建和操作对象:

public class CompositePatternDemo {public static void main(String[] args) {// 创建叶子节点Component emp1 = new Employee("Alice", "Developer");Component emp2 = new Employee("Bob", "Designer");Component emp3 = new Employee("Charlie", "Manager");// 创建容器节点Department engineering = new Department("Engineering Department");Department design = new Department("Design Department");// 将叶子节点添加到容器节点engineering.addEmployee(emp1);design.addEmployee(emp2);design.addEmployee(emp3);// 显示容器节点和叶子节点的详细信息engineering.showDetails();design.showDetails();}
}

详细解释

  1. Component 接口:定义了 showDetails 方法,这是叶子和容器共有的方法。
  2. Employee 类:实现了 Component 接口,它是叶子节点,表示没有子节点的对象,如具体的员工。
  3. Department 类:也是实现了 Component 接口,它是容器节点,表示可以包含子节点的对象,如部门。它有一个 List 来存储其包含的 Component 对象,并实现了 addEmployeeremoveEmployee 方法来管理这些子对象。
  4. CompositePatternDemo 类:客户端代码,演示了如何使用组合模式来创建和管理对象。它创建了具体的员工(叶子节点)和部门(容器节点),并展示了如何通过调用 showDetails 方法来显示所有对象的信息。

优缺点

优点

  • 清晰地定义了层次结构,可以轻松管理子对象的添加和删除。
  • 客户端可以统一地对待组合对象和单个对象,简化了代码。

缺点

  • 设计较为复杂,可能会增加系统的复杂性。
  • 容器与叶子之间的方法可能有不一致的情况。

总结

组合模式是一种强大的设计模式,它可以帮助你构建灵活的树形结构,并且使得客户端能够统一地处理单个对象和组合对象。通过使用组合模式,你可以更容易地扩展和维护系统。

相关文章:

设计模式--组合模式

组合模式&#xff08;Composite Pattern&#xff09;详解 组合模式是一种结构型设计模式&#xff0c;它允许你将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 适用场景 需要表示对象的部分-整体层次结构时&am…...

ArduPilot开源代码之AP_DAL_RangeFinder

ArduPilot开源代码之AP_DAL_RangeFinder 1. 源由2. 框架设计2.1 枚举 Status2.2 公有方法2.3 私有成员变量 3. 重要例程3.1 应用函数3.1.1 ground_clearance_cm_orient3.1.2 max_distance_cm_orient3.1.3 has_orientation3.1.4 get_backend 3.2 其他函数3.2.1 AP_DAL_RangeFind…...

SpringCloud教程 | 第九篇: 使用API Gateway

1、参考资料 SpringCloud基础篇-10-服务网关-Gateway_springcloud gateway-CSDN博客 2、先学习路由&#xff0c;参考了5.1 2.1、建了一个cloudGatewayDemo&#xff0c;这是用来配置网关的工程&#xff0c;配置如下&#xff1a; http://localhost:18080/aaa/name 该接口代码如…...

数据结构——hash(hashmap源码探究)

hash是什么&#xff1f; hash也称为散列&#xff0c;就是把任意长度的输入&#xff0c;通过散列算法&#xff0c;变成固定长度的输出&#xff0c;这个输出值就是散列值。 举例来说明一下什么是hash&#xff1a; 假设我们要把1~12存入到一个大小是5的hash表中&#xff0c;我们…...

国产麒麟、UOS在线打开pdf加盖印章

PageOffice支持两种电子印章方案&#xff0c;可实现对Word、Excel、PDF文档加盖PageOffice自带印章或ZoomSeal电子印章&#xff08;全方位保护、防篡改、防伪造&#xff09;。Word和Excel的盖章功能请参考&#xff1a;Word和Excel加盖印章和签字功能 &#xff08;目前只支持win…...

破解反爬虫策略 /_guard/auto.js(二)实战

这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略&#xff0c;这两个案例是两个不同的网站&#xff0c;一个用的是 /_guard/auto.js&#xff0c;另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样&#xff0c;只不过在js混淆和生成…...

同样是人工智能 客户在哪儿AI和GPT等大模型有什么不同

书接上回。为了统一回答朋友们的疑惑&#xff0c;此前的两篇文章&#xff0c;着重讲述了客户在哪儿AI的企业全历史行为数据和企业信息查询平台上的数据的区别&#xff0c;以及客户在哪儿AI的ToB获客服务和AI外呼机器人的获客服务的不同。本期接着讲——客户在哪儿AI VS 大模型&…...

AES Android IOS H5 加密方案

前景&#xff1a; 1、本项目原有功能RSA客户端对敏感信息进行加密 2、本次漏洞说是服务端返回值有敏感信息&#xff0c;需要密文返回 3、最初只跟H5联调成功&#xff0c;后续APP联调失败(H5和APP的需求排期不一致)&#xff0c;没关注到通用性 方案&#xff1a; 本次方案不…...

一文了解变阻器和电位器的定义、原理、应用及其对比

变阻器的定义 两端可变电阻器&#xff08;称为变阻器&#xff09;利用电阻来调节电流。电阻丝环绕在陶瓷或瓷器等绝缘芯上。当刮水器沿着电阻丝移动时&#xff0c;电路的有效电阻会发生变化。因此&#xff0c;它提供了精确的电流控制。调光器、电机速度控制器和加热元件使用变…...

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目&#xff0c;如下所示 2、创建文件夹及文件 创建资源文件夹&…...

使用Dockerfile构建镜像

目录 1.使用Dockerfile构建tomcat镜像 1.1 通过ARG传参构建不同版本的tomcat 2.缩小镜像的体积大小 2.1 使用较小体积的基础镜像 2.2 多级构建减少体积 1.使用Dockerfile构建tomcat镜像 cd /opt mkdir tomcat cd tomcat/ 上传tomcat所需的依赖包 使用tar xf 解压三个压缩…...

概率论原理精解【3】

文章目录 向量值向量值函数导数对称矩阵定义性质例子应用 向量值理论基础定义性质应用示例 向量值函数的导数定义性质应用 向量值 向量值函数导数 D n ⊂ R n , 向量值函数 f : D n → R m D^n \subset R^n,向量值函数f:D^n\rightarrow R^m Dn⊂Rn,向量值函数f:Dn→Rm 1. 向量…...

[C/C++入门][循环]14、计算2的幂(2的n次方)

计算2的幂&#xff08;即2的n次方&#xff09;非常经典。你懂几种方法呢&#xff1f;很多人只会一种&#xff0c;我们来分析一下。 可以通过多种方式实现&#xff1a; 1、最简单的方法之一是使用位运算符<<&#xff0c;它本质上是在二进制表示下对2进行左移操作&#x…...

RPC与服务的注册发现

文章目录 1. 什么是远程过程调用(RPC)?2. RPC的流程3. RPC实践4. RPC与REST的区别4.1 RPC与REST的相似之处4.2 RPC与REST的架构原则4.3 RPC与REST的主要区别 5. RPC与服务发现5.1 以zookeeper为服务注册中心5.2 以etcd为服务注册中心 6. 小结参考 1. 什么是远程过程调用(RPC)?…...

3112. 访问消失节点的最少时间 Medium

给你一个二维数组 edges 表示一个 n 个点的无向图&#xff0c;其中 edges[i] [ui, vi, lengthi] 表示节点 ui 和节点 vi 之间有一条需要 lengthi 单位时间通过的无向边。 同时给你一个数组 disappear &#xff0c;其中 disappear[i] 表示节点 i 从图中消失的时间点&#xff0…...

FastAPI 学习之路(五十二)WebSockets(八)接受/发送json格式消息

前面我们发送的大多数都是text类型的消息&#xff0c;对于text消息来说&#xff0c;后端处理出来要麻烦的多&#xff0c;那么我们可以不可以传递json格式的数据&#xff0c;对于前后端来说都比较友好&#xff0c;答案是肯定的&#xff0c;我们需要做下处理。 首先&#xff0c;…...

Go语言并发编程-案例_3

案例 并发目录大小统计 业务逻辑 统计目录的文件数量和大小&#xff08;或其他信息&#xff09;。示例输出&#xff1a; // 某个目录&#xff1a;2637 files 1149.87 MB 实现思路 给定一个或多个目录&#xff0c;并发的统计每个目录的size&#xff0c;最后累加到一起。 当…...

pikachu之跨站脚本攻击(x‘s‘s)

1get型 输入a看一下 接着输入<a> 发现<>没有被过滤当做标签处理了 尝试在表单提交的框里面&#xff0c;输入xss语句 尝试输入<script>alert(1)</script> 发现有长度限制 因为这里是get请求 get请求的特点是&#xff1a;传参是在url中的 所以我们可以在…...

Qt模型/视图架构——委托(delegate)

一、为什么需要委托 模型&#xff08;model&#xff09;用来数据存储&#xff0c;视图&#xff08;view&#xff09;用来展示数据。因此&#xff0c;模型/视图架构是一种将数据存储和界面展示分离的编程方法。具体如下图所示&#xff1a; 由图可知&#xff0c;模型向视图提供数…...

python3.11SSL: SSLV3_ALERT_HANDSHAKE_FAILURE

参考&#xff1a;python request包 版本不兼容 报错sslv3 alert handshake failure 解决方法-CSDN博客 修改&#xff1a;Python311\Lib\site-packages\urllib3\util\ssl_.py 新版本3.11里默认没有DEFAULT_CIPHERS 补回来: #__imported from 3.6.8 # A secure default. # So…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...