设计模式-组合模式

设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • 组合模式和装饰者模式的区别
    • 代码示例
      • Java实现组合模式
      • python实现组合模式
    • 组合模式在spring中的应用


模式介绍

组合模式是一种结构型设计模式,它针对由多个节点对象(部分)组成的树形结构的对象(整体)而发展。组合模式使得用户对单个对象和组合对象的使用具有一致性,它优化处理递归或分级数据结构。

组合模式的核心思想是将对象看作是一个树形结构,其中每个节点可以是一个单独的对象(叶子节点)或者一个包含其他节点的容器(组合节点)。叶子节点和组合节点都实现了相同的接口,这样客户端就可以对它们进行一致的操作,而不需要关心它们的具体类型。

组合模式的好处有:

  1. 可以将对象组合成树形结构,表示整体-部分的层次关系,符合人们的直觉。
  2. 可以统一处理单个对象和对象组合,简化了客户端的代码逻辑,提高了系统的可复用性。
  3. 可以遵循开闭原则,扩展性高,增加新的节点类型时不需要修改原有代码。

在这里插入图片描述

模式特点

组合模式的特点主要有:

  1. 递归结构 :组合模式将对象组织成树形结构,包括容器对象(组合对象)和叶子对象(单个对象)。容器对象可以包含其他容器对象和叶子对象,形成递归结构。
  2. 一致接口 :组合模式中,容器对象和叶子对象都实现相同的接口,使得客户端可以一致地操作它们。这样,客户端对单个对象和组合对象的使用具有一致性。
  3. 透明方式 :在透明组合模式中,所有管理子对象的方法都在Component中声明,包括Add,Remove等。这样做的好处是叶节点和枝节点对于外界没有区别,它们具备完全一致的接口。

总的来说,组合模式通过树形结构表示“整体-部分”的层次结构,并通过一致的接口处理单个对象和组合对象,实现了代码的高复用性和可扩展性。

在这里插入图片描述

应用场景

组合模式的应用场景非常广泛。比如在GUI界面设计中,组合模式可以用于构建复杂的用户界面。一个窗口可以包含多个控件,如按钮、文本框、标签等,这些控件可以被组合成一个面板,然后将面板添加到窗口中。面板本身也可以包含其他控件,从而形成一个树形结构。这种方式可以使界面设计更加灵活和可扩展。

此外,组合模式也适用于文件系统。一个目录可以包含多个文件和子目录,子目录本身也可以包含其他文件和子目录。这种方式可以使文件系统的结构更加清晰和易于管理。

组合模式适用于构建树形结构,表示“整体-部分”的层次关系。

  • 构建复杂的对象结构,表示整体与部分的关系。例如,在软件开发中,一个组件可能由多个子组件组成,这些子组件还可以包含其他组件,形成复杂的组件结构。
  • 需要一致地处理单个对象和组合对象的情况。在这种情况下,客户端代码无需区分对象是单独的对象还是组合对象,从而简化了客户端代码。
  • 需要透明地处理叶节点和枝节点的情况。在透明组合模式中,所有管理子对象的方法都在组合对象中声明,使得叶节点和枝节点对于外界没有区别,具备完全一致的接口。

在这里插入图片描述

组合模式和装饰者模式的区别

组合模式和装饰者模式都是设计模式中的结构型模式,但它们的目的和应用场景有所不同。

  • 组合模式是一种用于描述整体与部分关系的模式,它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性,客户端无需关心对象的内部结构,可以将复杂的对象树形结构当作一个整体对象来操作。

  • 装饰者模式是一种用于动态地给一个对象添加一些额外的职责的模式。它通过创建一个包装对象,其内部持有一个原始对象,并在包装对象中增加新的方法实现,这些新方法可以调用原始对象的相应方法。装饰者模式在不修改原始对象的前提下为其增加新的职责,它与组合模式的不同之处在于,装饰者模式是为了添加职责而设计,而组合模式是为了表示整体-部分的层次结构而设计。

组合模式关注的是构建复杂的对象结构,使得用户可以以一致的方式操作单个对象和组合对象;而装饰者模式关注的是在不修改原始对象的前提下动态地添加职责。

在这里插入图片描述

代码示例

Java实现组合模式

下面是一个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;
    }

    @Override
    public void operation() {
        System.out.println("Leaf " + name + ": operation executed.");
    }
}

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);
    }

    @Override
    public void operation() {
        for (Component child : children) {
            child.operation();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Composite composite = new Composite();
        Leaf leaf1 = new Leaf("1");
        Leaf leaf2 = new Leaf("2");
        Leaf leaf3 = new Leaf("3");
        composite.add(leaf1);
        composite.add(leaf2);
        composite.add(leaf3);
        composite.operation(); // 执行组合对象的操作,会依次执行所有叶子对象的操作
    }
}

在这个示例中,定义了一个Component接口,其中包含一个operation()方法。Leaf类和Composite类都实现了Component接口,其中Leaf类代表叶子节点,Composite类代表组合节点。Composite类中包含一个children列表,用于存储子节点。add()方法和remove()方法用于向children列表中添加或删除子节点。在operation()方法中,依次调用所有子节点的operation()方法。在主函数中,先创建一个组合对象,然后依次添加三个叶子对象,最后执行组合对象的operation()方法,会依次执行所有叶子对象的操作。

python实现组合模式

以下是使用Python实现组合模式的示例:

class Component:
    def operation(self):
        pass

class Leaf(Component):
    def operation(self):
        print("Leaf operation executed.")

class Composite(Component):
    def __init__(self):
        self._children = []
        
    def add(self, child):
        self._children.append(child)
        
    def remove(self, child):
        self._children.remove(child)
        
    def operation(self):
        print("Composite operation executed.")
        for child in self._children:
            child.operation()
            
if __name__ == '__main__':
    composite = Composite()
    leaf1 = Leaf()
    leaf2 = Leaf()
    leaf3 = Leaf()
    composite.add(leaf1)
    composite.add(leaf2)
    composite.add(leaf3)
    composite.operation() # 输出 "Composite operation executed." 和三次 "Leaf operation executed."

在这个示例中,我们定义了一个Component基类,它包含一个名为operation()的方法,但该方法没有实现。然后我们定义了一个Leaf类,它继承自Component并实现了operation()方法。我们还定义了一个Composite类,它也继承自Component,并包含一个子组件列表。Composite类实现了add()remove()方法来管理其子组件,并实现了operation()方法来执行其子组件的操作。在主函数中,我们创建了一个Composite对象并添加了三个Leaf对象作为其子组件。然后我们调用Composite对象的operation()方法来执行所有子组件的操作。

在这里插入图片描述

组合模式在spring中的应用

组合模式在Spring框架中有多种应用场景。例如,在Spring的依赖注入(Dependency Injection)中,可以使用组合模式来创建复杂的对象结构。

在Spring中,组合模式通常与Java的反射机制一起使用,以实现依赖注入。具体来说,Spring容器中的每一个bean都是一个独立的对象,可以通过反射获取其实例,并通过组合模式将其组合成复杂的对象结构。

例如,在Spring的XML配置中,可以使用元素来定义一个bean,并使用元素将其引用到另一个bean中。这样就可以将多个bean组合成一个复杂的对象结构,并通过依赖注入来实现对象之间的解耦。

除了依赖注入,组合模式还可以用于实现插件架构。例如,可以将一个复杂的对象拆分成多个插件,每个插件负责实现一部分功能,然后将这些插件组合起来形成一个完整的解决方案。这样可以方便地添加、删除或替换插件,而不影响整个系统的稳定性。

组合模式在Spring框架中有多种应用场景,可以用于实现复杂的对象结构、依赖注入和插件架构等功能。

在这里插入图片描述

设计模式-原型模式

设计模式-建造者模式

设计模式-工厂模式

设计模式-单例模式

设计模式-适配器模式

设计模式-装饰器模式

设计模式-代理模式

设计模式-外观模式

设计模式-桥接模式

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MES管理系统的应用场景都包括哪些

在当今高度信息化的时代&#xff0c;企业生产管理面临着越来越多的挑战。如何实现生产过程的数字化、智能化和优化&#xff0c;提高生产效率和产品质量&#xff0c;是许多制造企业亟待解决的问题。作为一种面向车间现场生产制造过程的数字化管理工具&#xff0c;MES管理系统在企…

最大公因数,最小公倍数详解

前言 对于初学编程的小伙伴们肯定经常遇见此类问题&#xff0c;而且为之头疼&#xff0c;今天我来给大家分享一下&#xff0c;最大公因数和最小公倍数的求法。让我们开始吧&#xff01; 文章目录 1&#xff0c;最大公因数法1法2法3 2&#xff0c;最小公倍数3&#xff0c;尾声 …

Linux安装Nginx并部署Vue项目

今天部署了一个Vue项目到阿里云的云服务器上&#xff0c;现记录该过程。 1. 修改Vue项目配置 我们去项目中发送axios请求的文件里更改一下后端的接口路由&#xff1a; 2. 执行命令打包 npm run build ### 或者 yarn build 打包成功之后&#xff0c;我们会看到一个dist包&a…

【Python】修改pip 默认安装位置

使用pip安装的时候&#xff0c;一般是默认安装在c盘里的。这样做很容易会让c盘的文件堆满。那么如何让pip安装的包放入d盘呢&#xff1f; 查看pip默认安装的位置 在cmd里输入python -m site&#xff0c;这里可以看到&#xff0c;安装包会默认下载到c盘中 从这里可以看到&am…

数据结构之----逻辑结构、物理结构

数据结构之----逻辑结构、物理结构 目前我们常见的数据结构分别有&#xff1a; 数组、链表、栈、队列、哈希表、树、堆、图 而它们可以从 逻辑结构和物理结构两个维度进行分类。 什么是逻辑结构&#xff1f; 逻辑结构是指数据元素之间的逻辑关系&#xff0c;而逻辑结构又分为…

基于深度学习的yolov5入侵检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介IntroductionYOLOv5 Overview入侵检测系统架构1. 数据采集2. YOLOv5模型训练3. 实时监测4. 告警与反馈 性能评估与优化 二、功能三、系统四. 总结 一项目简…

Nginx的server层外层的常见配置语句的解读

有下面的Nginx配置: worker_processes auto; worker_rlimit_nofile 51200;events {use epoll;worker_connections 51200;multi_accept on; }http {include mime.types;default_type application/octet-stream;server_names_hash_bucket_size 512;client_max_body_size 50m;cli…

锂电3V升12V1A升压芯片WT3209

锂电3V升12V1A升压芯片WT3209 WT3209是一款高功率密度全集成BOOST升压转换器&#xff0c;具备高效能解决方案。3V升12V1A,5V升12V1A WT3209内部集成的功率MOSFET管导通电阻为上管13mΩ和下管11mΩ&#xff0c;具备2A开关电流能力&#xff0c;并且能够提供高达12.6V的输出电压。…

代理模式:解析对象间的间接访问与控制

目录 引言 理解代理模式 不同类型的代理模式 代理模式的应用场景 代理模式的优缺点 优点 缺点 实际案例&#xff1a;Java中的代理模式应用 结语 引言 代理模式是软件设计模式中的一种结构型模式&#xff0c;旨在为其他对象提供一种代理以控制对这个对象的访问。它允许你…

Chrome谷歌浏览器安装VUE调试插件

访问gitee的vue-devtools 并下载 gitee地址&#xff1a;https://gitee.com/zhang_banglong/vue-devtools 也可以访问git的地址&#xff1a;https://github.com/vuejs/devtools 解压&#xff0c;放到自己的目录下 打开控制面板&#xff08;管理员&#xff09;&#xff0c;进入…

【技术分享】企业网必不可少的NAT技术

NAT是一种地址转换技术&#xff0c;它可以将IP数据报文头中的IP地址转换为另一个IP地址&#xff0c;并通过转换端口号达到地址重用的目的。NAT作为一种缓解IPv4公网地址枯竭的过渡技术&#xff0c;由于实现简单&#xff0c;得到了广泛应用。 NAT解决了什么问题&#xff1f; 随…

OneNote for Windows10 彻底删除笔记本

找了超多方法&#xff0c;都没有用&#xff0c;我的OneNote都没有文件选项&#xff0c;要在OneDrive中删除&#xff0c;但是一直登不进&#xff0c;然后又找到一个方法&#xff1a; 在网页中打开Office的控制面板 "Sign in to your Microsoft account" 在“最近”一…

C语言三种循环输出9*9乘法表

解题思路&#xff1a; 1、外层循环控制1~9循环 2、内层控制循环的次数 比如&#xff1a; 1 * 1 1 循环一次 1 * 1 1 1 * 2 循环两次 依此类推 int i, j;printf("for 打印9*9乘法表\r\n");for(i 1; i <10; i) {for(j 1; j < i;j) {printf("%d * %d %d…

el-tree搜索的使用

2023.12.11今天我学习了如何对el-tree进行搜索的功能&#xff0c;效果如下&#xff1a; <template><div class"head-container"><el-inputv-model"roleName"clearableplaceholder"请输入角色/用户名称"prefix-icon"el-icon-…

基于ssm连锁经营商业管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本连锁经营商业管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

快慢指针该如何操作?本文带你认识快慢指针常见的三种用法及在链表中的实战

很多同学都听过快慢指针这个名词&#xff0c;认为它不就是定义两个引用&#xff08;指针&#xff09;一前一后吗&#xff1f;是的&#xff0c;它的奥秘很深&#xff0c;它的作用究竟有哪些&#xff1f;究竟可以用来做哪些题目&#xff1f;下面我将一一带你了解和应用 下面的本节…

STM32 寄存器配置笔记——USART DMA发送

一、DMA介绍 直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传 输。无须CPU干预&#xff0c;数据可以通过DMA快速地移动&#xff0c;这就节省了CPU的资源来做其他操作。当产品对于时序要求较严格时&#xff0c;外设使用DMA的方式能够减轻CPU负…

C++ 指针常量和常量指针的区别

指针常量 指针常量&#xff1a;顾名思义它就是一个常量&#xff0c;但是是指针修饰的。 格式为&#xff1a; int * const p //指针常量在这个例子下定义以下代码&#xff1a; int a&#xff0c;b&#xff1b; int * const p&a //指针常量 //那么分为一下两种操作 *p9;//操…

[笔记] 使用 qemu/grub 模拟系统启动(单分区)

背景 最近在学习操作系统&#xff0c;需要从零开始搭建系统&#xff0c;由于教程中给的虚拟机搭建的方式感觉还是过于重量级&#xff0c;因此研究了一下通过 qemu 模拟器&#xff0c;配合 grub 完成启动系统的搭建。 qemu 介绍 qemu 是一款十分优秀的系统模拟器&#xff0c;…

软件设计师——软件工程(一)

&#x1f4d1;前言 本文主要是【软件工程】——软件设计师——软件工程的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304…