Java设计模式:结构型模式→组合模式

news2025/1/30 10:31:59

Java 组合模式详解

1. 定义

组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次。组合模式使得客户端能够以统一的方式对待单个对象和对象集合的一致性,有助于处理树形结构中双重角色的复杂性。

2. 基本思想

组合模式的基本思想在于通过一个统一的接口将所有的组件(即单个对象和组合对象)抽象为一种接口,这样在执行操作时,客户端就无需关心组件是单个对象还是组合对象。组合模式在设计时遵循了“合成复用原则”,可以通过简化操作和封装复杂性来提高代码的灵活性和可扩展性。

3. 基本原理

组合模式主要由以下部分构成:

  • 组件接口(Component):定义了树形结构中所有对象的接口,包括叶子节点(单个对象)和树枝节点(组合对象)的方法。
  • 叶子节点(Leaf):实现组件接口的具体类,表示树结构中的基本元素,不能包含子节点。
  • 树枝节点(Composite):同样实现组件接口,属于容器类型的对象,可以包含叶子节点或其他树枝节点。
    在这里插入图片描述

更多实用资源:

http://sj.ysok.net/jydoraemon 访问码:JYAM

4. 实现方式

4.1 基本实现

4.1.1 组件接口

定义一个组件接口,描述基本的操作:

public interface Component {
    void operation();
}
4.1.2 叶子节点类

实现叶子节点,表示树的基本元素:

public class Leaf implements Component {
    private String name;

    public Leaf(String name) {
        this.name = name;
    }

    @Override
    public void operation() {
        System.out.println("Leaf: " + name);
    }
}
4.1.3 树枝节点类

实现树枝节点,能够包含叶子和其他树枝:

import java.util.ArrayList;
import java.util.List;

public class Composite implements Component {
    private List<Component> children = new ArrayList<>();
    private String name;

    public Composite(String name) {
        this.name = name;
    }

    public void add(Component component) {
        children.add(component);
    }

    public void remove(Component component) {
        children.remove(component);
    }

    @Override
    public void operation() {
        System.out.println("Composite: " + name);
        for (Component child : children) {
            child.operation();
        }
    }
}
4.1.4 客户端代码

下面是客户端代码,展示如何使用组合模式:

public class Client {
    public static void main(String[] args) {
        Composite root = new Composite("Root");
        Leaf leaf1 = new Leaf("Leaf 1");
        Leaf leaf2 = new Leaf("Leaf 2");

        Composite composite1 = new Composite("Composite 1");
        Leaf leaf3 = new Leaf("Leaf 3");
        composite1.add(leaf3);

        root.add(leaf1);
        root.add(leaf2);
        root.add(composite1);

        root.operation(); // This will invoke the operation method for the whole structure
    }
}

4.2 代码分析

  • 组件接口(Component):定义了所有组件都必需实现的接口。这样,客户端可以使用统一的方式来操作。
  • 叶子节点(Leaf):实现组件接口,表示不能再加入子节点的对象,定义具体的业务逻辑。
  • 树枝节点(Composite):实现组件接口,持有所有子组件并实现对它们的管理,包括添加和移除子组件的功能。
  • 客户端:通过创建组合结构来组织组件,使得用户可以轻松操作复杂的对象结构。

5. 工作流程

  1. 定义组件接口:创建一个接口,提供所有组件需要实现的方法。
  2. 创建叶子节点类:实现组件接口,定义基本操作和具体业务。
  3. 创建树枝节点类:实现组件接口,管理子组件,包括添加、删除和操作子组件。
  4. 客户端使用组合:通过创建组合对象来添加叶子节点和其他树枝节点,统一管理整个结构。

6. 变种

  1. 递归组合:可以实现更复杂的组合,通过子组合继续组合形成多层结构。
  2. 安全组合:结合访问控制,只允许特定对组合的访问方式,以控制树的完整性。

7. 实际应用

组合模式在实际应用中广泛存在,以下是一些典型应用场景:

  1. 文件系统:文件和目录之间的关系可以用组合模式表示,目录可以包含文件和其它目录。
  2. GUI 组件:在图形用户界面中,组件和容器(如窗口、面板)之间的关系可以用组合模式管理。
  3. 组织结构:处理公司或团队的组织结构,部门(树枝节点)可以包含员工(叶子节点)、其他部门(树枝节点)等。

8. 使用场景

使用组合模式的场景包括:

  • 当客户端需要统一处理单个对象和组合对象时。
  • 当你需要用树形结构表现对象的组合关系时。
  • 当你希望能够增加新的叶子和组合节点而无须改变现有代码时。

9. 优缺点

优点

  1. 简化客户端代码:客户端通过统一的接口与组件交互,无需关心树的结构。
  2. 灵活性:可以轻松添加新叶子和新的组合、维持已有结构。
  3. 高层次的透明性:客户端可以一致地对待树的节点和组合。

缺点

  1. 实现复杂性:逻辑上的复杂性可能会增加,特别是在处理组合时。
  2. 性能问题:对于非常深的组合结构,可能会造成性能问题,推迟操作实现。

10. 最佳实践

  1. 避免过度组合:组合结构应适度,避免组合生成过长的结构,减低可维护性。
  2. 使用统一接口:确保所有组件实现统一的接口,以增加灵活性和可扩展性。
  3. 固定接口设计:组件接口应尽量保持稳定以避免频繁的修改。

11. 注意事项

  1. 管理树的变化:设计树的结构时,避免频繁修改或调整结构,以防引入逻辑错误。
  2. 处理复杂性:注意过度设计,简单结构需保持简单。
  3. 性能监测:考虑树的深度和广度,在性能敏感的场景中小心使用。

12. 常见的误区

  • 组合模式仅适用于树形结构:实际上,它可以用于其他潜在的组合关系,具备组织的灵活性。
  • 认为组合模式只为复杂系统设计:组合模式同样适用于简单的、几乎不复杂的系统结构,以保持强一致性。

13. 常见问题

  • 如何判断使用组合模式呢?

    • 通常在有“部分-整体”结构需要处理时,就考虑使用组合模式。
  • 组合模式的核心组成部分是什么?

    • 树形结构的组成部分有组件接口、叶子节点类、树枝节点类和客户端。
  • 组合模式如何处理节点的状态变化?

    • 通过组件接口中的方法定义所需的状态变更,树的任何节点均可变化并影响整个结构。

14. 总结

组合模式是一种强大的设计模式,它简化了树形结构中复杂对象的管理与交互。通过建立一个统一接口,使得客户端能够轻松操作组合的对象,增强了代码的可读性、可维护性和扩展性。在实际开发中,合理运用组合模式不仅能够提升软件的质量,还能有效管理复杂的业务需求。通过对组合模式的掌握与经验积累,开发者能更好地设计出灵活、易扩展的应用程序。

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

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

相关文章

【福州市AOI小区面】shp数据学校大厦商场等占地范围面数据内容测评

AOI城区小区面样图和数据范围查看&#xff1a; — 字段里面有name字段。分类比较多tpye&#xff1a;每个值代表一个类型。比如字段type中1549代表小区住宅&#xff0c;1563代表学校。小区、学校等占地面积范围数据 —— 小区范围占地面积面数据shp格式 无偏移坐标&#xff0c;只…

【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR

【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR 1 算法原理 Tarun A K, Chundawat V S, Mandal M, et al. Fast yet effective machine unlearning[J]. IEEE Transactions on Neural Networks and Learning Systems, 2023. 本文提出了一种名为 UNSIR&#xff08;Un…

基于SpringBoot的阳光幼儿园管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【开源免费】基于SpringBoot+Vue.JS景区民宿预约系统(JAVA毕业设计)

本文项目编号 T 162 &#xff0c;文末自助获取源码 \color{red}{T162&#xff0c;文末自助获取源码} T162&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

安卓逆向之脱壳-认识一下动态加载 双亲委派(一)

安卓逆向和脱壳是安全研究、漏洞挖掘、恶意软件分析等领域的重要环节。脱壳&#xff08;unpacking&#xff09;指的是去除应用程序中加固或保护措施的过程&#xff0c;使得可以访问应用程序的原始代码或者数据。脱壳的重要性&#xff1a; 分析恶意软件&#xff1a;很多恶意软件…

马尔科夫模型和隐马尔科夫模型区别

我用一个天气预报和海藻湿度观测的比喻来解释&#xff0c;保证你秒懂&#xff01; 1. 马尔可夫模型&#xff08;Markov Model, MM&#xff09; 特点&#xff1a;状态直接可见 场景&#xff1a;天气预报&#xff08;晴天→雨天→阴天…&#xff09;核心假设&#xff1a; 下一个…

Python NumPy(7):连接数组、分割数组、数组元素的添加与删除

1 连接数组 函数描述concatenate连接沿现有轴的数组序列stack沿着新的轴加入一系列数组。hstack水平堆叠序列中的数组&#xff08;列方向&#xff09;vstack竖直堆叠序列中的数组&#xff08;行方向&#xff09; 1.1 numpy.concatenate numpy.concatenate 函数用于沿指定轴连…

【LLM】deepseek多模态之Janus-Pro和JanusFlow框架

note 文章目录 note一、Janus-Pro&#xff1a;解耦视觉编码&#xff0c;实现多模态高效统一技术亮点模型细节 二、JanusFlow&#xff1a;融合生成流与语言模型&#xff0c;重新定义多模态技术亮点模型细节 Reference 一、Janus-Pro&#xff1a;解耦视觉编码&#xff0c;实现多模…

2000-2021年 全国各地级市专利申请与获得情况、绿色专利申请与获得情况数据

2000-2021年 全国各地级市专利申请与获得情况、绿色专利申请与获得情况数据.ziphttps://download.csdn.net/download/2401_84585615/89575931 https://download.csdn.net/download/2401_84585615/89575931 2000至2021年&#xff0c;全国各地级市的专利申请与获得情况呈现出显著…

51单片机(STC89C52)开发:点亮一个小灯

软件安装&#xff1a; 安装开发板CH340驱动。 安装KEILC51开发软件&#xff1a;C51V901.exe。 下载软件&#xff1a;PZ-ISP.exe 创建项目&#xff1a; 新建main.c 将main.c加入至项目中&#xff1a; main.c:点亮一个小灯 #include "reg52.h"sbit LED1P2^0; //P2的…

240. 搜索二维矩阵||

参考题解&#xff1a;https://leetcode.cn/problems/search-a-2d-matrix-ii/solutions/2361487/240-sou-suo-er-wei-ju-zhen-iitan-xin-qin-7mtf 将矩阵旋转45度&#xff0c;可以看作一个二叉搜索树。 假设以左下角元素为根结点&#xff0c; 当target比root大的时候&#xff…

反向代理模块b

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…

【Linux权限】—— 于虚拟殿堂,轻拨密钥启华章

欢迎来到ZyyOvO的博客✨&#xff0c;一个关于探索技术的角落&#xff0c;记录学习的点滴&#x1f4d6;&#xff0c;分享实用的技巧&#x1f6e0;️&#xff0c;偶尔还有一些奇思妙想&#x1f4a1; 本文由ZyyOvO原创✍️&#xff0c;感谢支持❤️&#xff01;请尊重原创&#x1…

EasyExcel使用详解

文章目录 EasyExcel使用详解一、引言二、环境准备与基础配置1、添加依赖2、定义实体类 三、Excel 读取详解1、基础读取2、自定义监听器3、多 Sheet 处理 四、Excel 写入详解1、基础写入2、动态列与复杂表头3、样式与模板填充 五、总结 EasyExcel使用详解 一、引言 EasyExcel 是…

前端-Rollup

Rollup 是一个用于 JavaScript 的模块打包工具&#xff0c;它将小的代码片段编译成更大、更复杂的代码&#xff0c;例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式&#xff0c;而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…

vue3相关知识点

title: vue_1 date: 2025-01-28 12:00:00 tags:- 前端 categories:- 前端vue3 Webpack ~ vite vue3是基于vite创建的 vite 更快一点 一些准备工作 准备后如图所示 插件 Main.ts // 引入createApp用于创建应用 import {createApp} from vue // 引入App根组件 import App f…

微服务网关鉴权之sa-token

目录 前言 项目描述 使用技术 项目结构 要点 实现 前期准备 依赖准备 统一依赖版本 模块依赖 配置文件准备 登录准备 网关配置token解析拦截器 网关集成sa-token 配置sa-token接口鉴权 配置satoken权限、角色获取 通用模块配置用户拦截器 api模块配置feign…

华为小米vivo向上,苹果荣耀OPPO向下

日前&#xff0c;Counterpoint发布的手机销量月度报告显示&#xff0c;中国智能手机销量在2024年第四季度同比下降3.2%&#xff0c;成为2024年唯一出现同比下滑的季度。而对于各大智能手机品牌来说&#xff0c;他们的市场份额和格局也在悄然发生变化。 华为逆势向上 在2024年第…

国产编辑器EverEdit - 输出窗口

1 输出窗口 1.1 应用场景 输出窗口可以显示用户执行某些操作的结果&#xff0c;主要包括&#xff1a; 查找类&#xff1a;查找全部&#xff0c;筛选等待操作&#xff0c;可以把查找结果打印到输出窗口中&#xff1b; 程序类&#xff1a;在执行外部程序时(如&#xff1a;命令窗…

获取snmp oid的小方法1(随手记)

snmpwalk遍历设备的mib # snmpwalk -v <SNMP version> -c <community-id> <IP> . snmpwalk -v 2c -c test 192.168.100.201 .根据获取的值&#xff0c;找到某一个想要的值的oid # SNMPv2-MIB::sysName.0 STRING: test1 [rootzabbix01 fonts]# snmpwalk -v…