组合模式 (Composite Pattern)

定义:

组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示部分-整体的层次关系。这种模式创建了一种包含单个对象和组合对象的统一接口,使得客户端可以以统一的方式处理单个对象和组合对象。

组合模式的关键特点包括:

  1. 统一的接口:组合模式提供了一个统一的接口来管理单个对象和组合对象。这个接口可以是抽象类或者接口。
  2. 树形结构:组合模式允许客户以一致的方式处理单个对象和组合对象。例如,图形界面的组件(如窗口、面板、按钮)可以形成一种树形结构,其中每个组件既可以是单个元素,也可以是包含其他元素的容器。
  3. 透明性:在组合模式中,客户端代码使用单个对象和组合对象的方式相同,这提供了透明性。客户端不需要关心它正在处理的是单个对象还是整个组合结构。

组合模式通常涉及以下几个角色:

  • 组件(Component):定义了所有对象共有的接口,包括单个对象和组合对象。
  • 叶子(Leaf):表示组合中的单个对象,实现或继承组件接口。
  • 组合(Composite):定义了包含子部件(子叶子或子组合)的那些对象的行为。组合对象可以存储组件,实现组件接口中与子部件相关的操作。

组合模式主要用于处理具有层次结构的对象,使得客户端可以忽略层次结构的差异,统一地处理层次结构中的所有对象。

解决的问题:
  • 统一处理单个对象和组合对象
    • 在很多场景中,客户端需要以统一的方式处理单个对象和组合对象。组合模式允许客户端无差别地对待单个对象和由多个对象组成的复合对象。
  • 简化客户端代码
    • 客户端可以一致地处理复杂的树形结构,而不必关心处理的是单个对象还是组合对象,简化了客户端的代码逻辑。
  • 表示对象的部分-整体层次结构
    • 组合模式非常适合于表达和管理对象的部分-整体层次结构,如图形界面中的组件结构、文档结构、目录结构等。
  • 增加和删除节点方便
    • 组合模式使得在运行时添加或删除节点成为可能,提供了高度的灵活性。可以动态地修改树形结构,而不需要修改现有代码。
  • 简化复杂对象的创建过程
    • 通过递归组合,可以构建复杂的对象树形结构,简化了复杂对象创建过程的复杂性。
  • 更好的分层管理
    • 组合模式通过树形结构提供了自然的层次分界,有助于更好地组织和管理复杂的系统。

组合模式的关键在于它提供了一种统一处理个别对象和对象组合的方式,使得客户端代码可以一致地对待单个对象和组合对象。这种模式特别适用于那些元素构成具有明显层次关系且需要统一管理的场景。

使用场景:
  • 图形用户界面组件
    • 在图形用户界面(GUI)中,如窗口、面板、按钮等组件常常形成树形结构。使用组合模式可以统一处理单个控件和控件组。
  • 文件和目录的管理
    • 在文件系统中,文件和目录的关系可以用组合模式来表示。目录可以包含文件或其他目录,但对用户来说,它们的操作方式是一致的。
  • 组织架构
    • 在处理公司或其他组织的组织架构时,组合模式可以用来表示和处理单个员工和员工组(如部门)。
  • XML或HTML文档结构
    • 在解析和处理XML或HTML文档时,组合模式能够提供一种统一处理元素和元素集合的方式。
  • 产品部件的构建
    • 在设计产品的部件时,如设计一个家具系列,组合模式可以用来设计和组合不同的部件。
  • 图形绘制
    • 在图形绘制应用程序中,可以用组合模式来处理和操作图形和图形组。
  • 菜单系统
    • 在创建菜单系统时,菜单项可以是简单的动作或包含其他菜单项的子菜单,使用组合模式可以方便地构建和管理这样的菜单结构。

这些场景共同的特点是它们涉及到一组对象和单个对象之间存在相似的处理方式,且这些对象在概念上构成一个层次结构。组合模式通过将对象组织成树形结构,提供了一种统一且简洁的方式来处理这类场景。

示例代码 1 - 概念实现:
// 抽象组件
public interface Component {void operation();
}// 叶子组件
public class Leaf implements Component {@Overridepublic void operation() {System.out.println("Leaf operation.");}
}// 组合组件
public 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);}public Component getChild(int index) {return children.get(index);}@Overridepublic void operation() {for (Component child : children) {child.operation();}}
}
示例代码2 - 文件系统:
// 抽象组件
public abstract class FileSystemComponent {protected String name;public FileSystemComponent(String name) {this.name = name;}public abstract void showDetails();
}// 叶子组件 - 文件
public class File extends FileSystemComponent {public File(String name) {super(name);}@Overridepublic void showDetails() {System.out.println("File: " + name);}
}// 组合组件 - 文件夹
public class Directory extends FileSystemComponent {private List<FileSystemComponent> components = new ArrayList<>();public Directory(String name) {super(name);}public void add(FileSystemComponent component) {components.add(component);}public void remove(FileSystemComponent component) {components.remove(component);}@Overridepublic void showDetails() {System.out.println("Directory: " + name);for (FileSystemComponent component : components) {component.showDetails();}}
}// 使用组合模式
public class CompositePatternDemo {public static void main(String[] args) {FileSystemComponent file1 = new File("File1.txt");FileSystemComponent file2 = new File("File2.jpg");FileSystemComponent file3 = new File("File3.pdf");FileSystemComponent directory = new Directory("Directory1");directory.add(file1);directory.add(file2);directory.add(file3);directory.showDetails(); // 显示目录及其包含的文件}
}
主要符合的设计原则:
  1. 开闭原则(Open-Closed Principle):
    • 组合模式允许在不修改现有代码的情况下扩展新的元素。你可以添加新的组件(即叶子节点或组合节点)而不改变已有代码的结构,这使得系统对于扩展是开放的,对于修改是封闭的。
  2. 单一职责原则(Single Responsibility Principle):
    • 组合模式允许将操作分配到各个对象的单一职责上。例如,在树形结构中,每个节点(无论是叶子节点还是组合节点)负责管理自己的子节点。
  3. 最少知识原则(Principle of Least Knowledge)/迪米特法则(Law of Demeter):
    • 客户端代码仅与树形结构的最高层级交互,无需了解内部细节,减少了对象间的相互作用。
在JDK中的应用:
  • Swing GUI组件
    • Java Swing库广泛使用了组合模式。在Swing中,组件树的结构允许你以统一的方式处理单个组件(如按钮、标签)和复合组件(如面板)。例如,JPanel 可以包含其他组件,包括其他 JPanel 对象。
  • Java AWT组件
    • 类似于Swing,Java的抽象窗口工具包(AWT)中的组件也使用了组合模式。这些组件包括 Container 类及其子类,如 PanelFrame,它们可以包含其他组件,形成一个层次结构。
  • JavaFX
    • 在JavaFX中,场景图(Scene Graph)的构建也是基于组合模式的一个实例。场景图中的节点可以是叶子节点,如形状和文本,也可以是组合节点,如布局容器。
  • Java集合框架
    • 虽然Java集合框架(Java Collections Framework)主要是基于迭代器模式构建的,但在某种程度上也可以看作是组合模式的一种应用。例如,MapList 接口都可以包含其他对象的集合,这些对象也可以是复合类型。

在这些例子中,组合模式提供了一种处理对象集合的有效方式,无论这些对象是单一的还是构成更复杂的结构。通过将对象组织成树形结构,组合模式使得客户端能以统一的方式处理单个对象和组合对象。

在Spring中的应用:
  • Spring配置类的组合
    • 在Spring中,配置类(带有@Configuration注解的类)可以相互组合,一个配置类可以包含另一个配置类,从而创建层次化的配置结构。这种配置的嵌套和组合反映了组合模式的特征。
  • Spring Security权限控制
    • 在Spring Security中,权限控制的实现可能涉及到将多个权限规则组合成更复杂的访问控制策略。例如,可以将多个权限表达式组合成一个更大的表达式,这与组合模式的思想相符。
  • Spring MVC中的视图解析
    • 在Spring MVC中,可以配置多个视图解析器,它们可以按顺序组合起来工作,以解析不同类型的视图。这种视图解析器的组合使用了组合模式的思想。
  • Bean定义与继承
    • Spring框架中的BeanDefinitionBeanDefinitionRegistry使用组合模式,允许管理多个Bean定义,将单个Bean和Bean集合以统一方式处理。

这些应用案例表明,尽管Spring不直接声明使用组合模式,但在处理对象和配置的组合、层次化结构方面,Spring的设计确实借鉴了组合模式的思想。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

刷题记录第三十五天-(KMP算法)找出字符串中的第一个匹配项的下标

KMP算法真是刷一次忘一次 #include<bits\stdc.h> using namespace std; void get_next(vector<int>& next, string s){int j0;next[0]0;for(int i1;i<s.size();i){while(j>0&&s[i]!s[j]){jnext[j-1];}if(s[i]s[j])j;next[i]j;} } int find(strin…

第19章JAVA绘图

19.1JAVA绘图类 绘图是高级程序设计中非常重要的技术 19.1.1Graphics类 Graphics类是所有图形上下文的抽象基类&#xff0c;它允许应用程序在组件以及闭屏图片上进行绘制 Graphics类封装了JAVA支持的基本绘图操作所需的状态信息&#xff0c;主要包括颜色&#xff0c;字体&…

快速了解Spring AOP的概念及使用

文章目录 1. AOP概念1.1 什么是AOP&#xff1f;1.2 什么是Spring AOP&#xff1f; 2. Spring AOP的使用2.1 引入Spring AOP依赖2.2 编写AOP程序 3. Spring AOP详解3.1 Spring AOP核心概念1. 切点&#xff08;Pointcut&#xff09;2. 连接点&#xff08;Join Point&#xff09;3…

AI模型推理(5)——实战篇(持续更新)

前言 本文主要通过实战的方式&#xff0c;记录各种模型推理的方法 模型训练 首先我们先使用Pytorch训练一个最简单的十分类神经网络&#xff0c;如下&#xff1a; import torch from torch import nn from torch.utils.data import DataLoader from torchvision import data…

如何运用AppLink平台中的数据连接器组件

AppLink平台组件组成 AppLink平台组件分成三个板块触发事件组件、基础组件和数据连接器 数据连接器组件里面有10个组件&#xff0c;目前也在不断新增更多的数据连接器&#xff0c;那他们在AppLink平台里的原理、触发动作以及怎么使用呢&#xff1f;接下来用MySQL和TimescaleD…

在线陪诊系统: 医疗科技的崭新前沿

在医学科技的快速发展中&#xff0c;在线陪诊系统正成为医疗服务领域的创新力量。通过结合互联网和先进的远程技术&#xff0c;这一系统为患者和医生提供了更为便捷、高效的医疗体验。本文将深入探讨在线陪诊系统的技术背后的核心代码和实现原理。 技术背后的关键代码 在线陪…

用于图像分类任务的经典神经网络综述

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

autojs-图片篇(一)

注释很详细&#xff0c;直接上代码 自动点击授予权限的操作 //安卓版本高于Android 9 if(device.sdkInt>28){//等待截屏权限申请并同意threads.start(function () {packageName(com.android.systemui).text(立即开始).waitFor();text(立即开始).click();}); }截图查相应位置…

开关电源做“做安规”请记住这 4 点!

1.定义 为了保证人身安全,财产,环境等不受伤害和损失,所做出的规定。 2.安规所涉及的要求 a.电击 b.火灾 c.电磁辐射 d.环境污染 e.化学辐射 f.能量冲击 g.化学腐蚀 h.机械伤害和热伤害 3.世界主要安规体系 a.IEC体系----以欧盟为代表 b.UL体系----以美国为代表…

55.跳跃游戏

原题链接&#xff1a;55.跳跃游戏 思路&#xff1a; 看代码注释 全代码&#xff1a; class Solution { public:bool canJump(vector<int>& nums) {int cover 0;if (nums.size() 1) return true; // 只有一个元素&#xff0c;就是能达到for (int i 0; i < co…

探索性因子分析流程

探索性因子分析的步骤&#xff1a; 接下来&#xff0c;通过一个案例演示因子分析&#xff08;探索性因子分析&#xff09;的各个步骤应该如何进行。 案例&#xff1a;欲探究我国不同省份铁路运输能力情况&#xff0c;收集到部分相关数据如下&#xff1a; 上传数据至SPSSAU系统…

echarts 水波图

echarts 水波图 安装 npm install echarts --save npm install echarts-liquidfill --save引入 import * as echarts from echarts; import echarts-liquidfill;html <div id"chart1" ref"chart1" class"chart1"></div>css .cha…

leetcode做题笔记1670. 设计前中后队列

请你设计一个队列&#xff0c;支持在前&#xff0c;中&#xff0c;后三个位置的 push 和 pop 操作。 请你完成 FrontMiddleBack 类&#xff1a; FrontMiddleBack() 初始化队列。void pushFront(int val) 将 val 添加到队列的 最前面 。void pushMiddle(int val) 将 val 添加到…

RequestContextHolder 类简介

RequestContextHolder 类简介 RequestContextHolder是Spring Framework中的一个类&#xff0c;用于在多线程环境中存储和访问HTTP请求的上下文信息。它允许在Spring应用程序中从任何位置访问当前请求的相关信息&#xff0c;如HTTP头部、会话数据等&#xff0c;而无需将请求对象…

C语言实现串的部分算法

一、简介 串&#xff08;string&#xff09;&#xff08;或字符串&#xff09;是由零个或多个字符组成的有序序列&#xff0c;一般记为 sa1a2....an s为串的名&#xff0c;用单引号括起来的时字符序列串的值&#xff0c;串中字符的数目n称为串的长度。 零个字符的串称为空串…

C语言--每日选择题--Day28

第一题 1. 设a和b均为double型变量&#xff0c;且a5.5、b2.5&#xff0c;则表达式(int)ab/b的值是&#xff08; &#xff09; A&#xff1a;6.500000 B&#xff1a;6 C&#xff1a;5.500000 D&#xff1a;6.000000 答案及解析 D 本题考查的是不同数据类型之间的变量进行运算时…

常见面试题-Redis 切片集群以及主节点选举机制

Redis 切片集群了解吗&#xff1f; 答&#xff1a; Redis 切片集群是目前使用比较多的方案&#xff0c;Redis 切面集群支持多个主从集群进行横向扩容&#xff0c;架构如下&#xff1a; 使用切片集群有什么好处&#xff1f; 提升 Redis 读写性能&#xff0c;之前的主从模式中&…

使用C语言库函数qsort排序注意点

目录 题目背景错误C语言代码&#xff1a;正确C语言代码&#xff1a;注意点 题目背景 高校团委组织校园歌手比赛&#xff0c;进入决赛的校园歌手有10位,歌手编号从1到10进行编号。组委会随机抽取方式产生了决赛次序为&#xff1a;3,1,9,10,2,7,5,8,4,6。比赛现场有5个评委为参赛…

【Docker项目实战】使用Docker部署Plik临时文件上传系统

【Docker实战项目】使用Docker部署Plik 临时文件上传系统 一、Plik介绍1.1 Plik简介1.2 Plik特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Plik镜像五、部署Plik临时…

PLC:200smart

PLC&#xff1a;200smart 第十章、数据类型、数据存储1、数据类型1.1、有符号数1.2、有符号数 2、传送指令 第十一章、比较指令、整数、浮点数的运算1、比较指令1、运算指令1.1、浮点数运算1.2、整数运算 第十章、数据类型、数据存储 1、数据类型 数据类型分为两大类 无符号数…