Java特性之设计模式【组合模式】

一、组合模式

概述

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式

主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦

何时使用:1、想表示对象的部分-整体层次结构(树形结构) 2、希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象

优缺点

优点:

  • 组合模式通过递归的形式遍历组合对象,使得对象可以无限层次地嵌套。这样可以更加灵活地表示复杂的结构,并能够方便地对整个结构进行操作
  • 通过组合模式,以统一的方式处理整体和部分,不需要关心当前操作的对象是叶节点还是组合节点,可以统一地进行操作

缺点:

  • 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则

1. 各个角色介绍

1.1 组件(Component)

  • 定义了组合中所有对象的通用接口,可以是抽象类或接口。它声明了用于访问和管理子组件的方法,包括添加、删除、获取子组件等

1.2 叶子节点(Leaf)

  • 表示组合中的叶子节点对象,叶子节点没有子节点。它实现了组件接口的方法,但通常不包含子组件

1.3 复合节点(Composite)

  • 表示组合中的复合对象,复合节点可以包含子节点,可以是叶子节点,也可以是其他复合节点。它实现了组件接口的方法,包括管理子组件的方法

2. UML图

​ 我们有一个类 Component 对象作为所有对象的通用接口,然后 LeafComposite 分别实现该接口,并通过 Composite 构建非叶子节点和叶子节点,形成树状图,并以中序遍历的形式输出

在这里插入图片描述

3. 具体例子和代码

角色分配

  • Component:抽象组件
  • Leaf:叶子节点(叶子节点下,无组件,继承Component)
  • Composite:组合节点(继承Component)

3.1 抽象组件

  • Component
package com.vinjcent.prototype.composite;

import io.swagger.annotations.ApiModelProperty;

/**
 * @author vinjcent
 * @description 抽象组件
 * @since 2024/3/11 22:16
 */
public abstract class Component {

    @ApiModelProperty("组件名称")
    protected String name;

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

    /**
     * 组件操作
     */
    public abstract void operation();

    /**
     * 为当前组件添加组件
     *
     * @param component 需要添加的组件
     */
    public abstract void add(Component component);

    /**
     * 移除某一组件
     *
     * @param component 需要移除的组件
     */
    public abstract void remove(Component component);

    /**
     * 根据下标获取子组件
     *
     * @param index 下标
     * @return 下标对应组件
     */
    public abstract Component getChild(int index);

}

3.2 叶子节点

  • Leaf
package com.vinjcent.prototype.composite;

/**
 * @author vinjcent
 * @description 叶子节点(叶子节点下,无组件)
 * @since 2024/3/11 22:20
 */
public class Leaf extends Component {

    public Leaf(String name) {
        super(name);
    }

    public void operation() {
        System.out.println("Leaf " + name + " is performing operation.");
    }

    public void add(Component component) {
        // 在叶节点中无法添加子节点,可以选择抛出异常或忽略该操作
        throw new UnsupportedOperationException("Unsupported operation: add");
    }

    public void remove(Component component) {
        // 在叶节点中无法移除子节点,可以选择抛出异常或忽略该操作
        throw new UnsupportedOperationException("Unsupported operation: remove");
    }

    public Component getChild(int index) {
        // 叶节点没有子节点,返回null或抛出异常
        return null;
    }
}

3.3 组合节点

  • Composite
package com.vinjcent.prototype.composite;

import io.swagger.annotations.ApiModelProperty;

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

/**
 * @author vinjcent
 * @description 组合节点
 * @since 2024/3/11 22:44
 */
public class Composite extends Component {

    @ApiModelProperty("子节点")
    private List<Component> children;

    public Composite(String name) {
        super(name);
        children = new ArrayList<>();
    }

    @Override
    public void operation() {

        System.out.println("Composite " + name + " is performing operation.");
        for (Component child : children) {
            child.operation();
        }

    }

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

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

    @Override
    public Component getChild(int index) {
        return children.get(index);
    }
}

3.4 测试主函数

package com.vinjcent.prototype.composite;

/**
 * @author vinjcent
 * @description 组合模式
 * @since 2024/3/11 22:51:07
 */
public class Main {

    public static void main(String[] args) {

        // 根节点
        Component root = new Composite("Root");

        // 叶子节点1、2
        Component leaf1 = new Leaf("L. one");
        Component leaf2 = new Leaf("L. two");

        // 子节点1
        Component node1 = new Composite("N. one");
        Component leaf3 = new Leaf("L. three");

        // 子节点2
        Component node2 = new Composite("N. two");
        Component leaf4 = new Leaf("L. four");

        // 为子节点添加叶子节点
        node1.add(leaf3);
        node2.add(leaf4);

        // 为根节点添加子节点、叶子节点
        root.add(leaf1);
        root.add(leaf2);
        root.add(node1);
        root.add(node2);

        // 输出结果,相当于中序遍历
        root.operation();

    }

}

  • 测试结果

在这里插入图片描述

4. 使用场景

  • 部分、整体场景,如树形菜单,文件、文件夹的管理
    在这里插入图片描述

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

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

相关文章

隐私计算实训营学习一:数据可信流通,从运维信任到技术信任

文章目录 一、数据可信流通二、数据可信流通的技术信任基础三、技术信任开启数据密态时代&#xff0c;保障广域数据可信流通 一、数据可信流通 可信数据流通体系&#xff1a;数据二十条第一次明确提出可信流通&#xff0c;建立数据来源可确认、使用范围可界定、流通过程可追溯…

金融知识分享系列之:支撑阻力

金融知识分享系列之&#xff1a;支撑阻力 一、支撑阻力原理二、支撑阻力作用1.识别市场资金的预期2.作为入场和平仓的重要参考 三、寻找支撑阻力四、延伸思考五、支撑阻力总结 一、支撑阻力原理 支撑阻力核心要素&#xff1a; 锚定效应订单驱动 支撑阻力原理&#xff1a; 市…

在DevEco Studio中第一次使用网络图片不显示问题

当我们新建项目 第一次使用网络图片 没有显示时 加这段代码就可以了 如果刷新图片还是没有显示 就重启编辑器。 "requestPermissions": [{"name": "ohos.permission.INTERNET"}],

>>Vue3+pinia+echarts等实现疫情可视化大图

一.>>前言 1.这个项目是在小满实战篇可视化&#xff08;第九章-饼图&#xff09;_哔哩哔哩_bilibili 这一系列课程为基础来做的&#xff0c;真的很感谢小满老师&#xff0c;讲的内容干货满满&#xff0c;暂时解决了手上没有项目的难题。大家可以去观摩一下他的优质课程。…

WT32-ETH02 plus 串口转以太网开发,WT32-ETH01网关开发板升级款!

广受欢迎的WT32-ETH01网关开发板迎来了升级。 就是这款启明云端新推出的嵌入式串口转以太网开发板——WT32-ETH02 plus。应广大客户的需求&#xff0c;在WT32-ETH01的基础上增加了POE供电&#xff0c;可广泛应用于智能家居和网关等应用。开发板搭载2.4GHz Wi-Fi和蓝牙双模的SO…

PyTorch 深度学习(GPT 重译)(五)

十二、通过指标和增强改进训练 本章涵盖 定义和计算精确率、召回率以及真/假阳性/阴性 使用 F1 分数与其他质量指标 平衡和增强数据以减少过拟合 使用 TensorBoard 绘制质量指标图 上一章的结束让我们陷入了困境。虽然我们能够将深度学习项目的机制放置好&#xff0c;但实…

shell编程入门(笔记)

1、shell编程基础&#xff1a; 1.1、shell的解释执行功能 1.2、什么是shell程序&#xff1f; 1.3、shell程序编程的主要内容 1.4、shell程序的第一行 1.5、变量要求 1.6、环境变量和只读变量 1.7、位置参量 1.8、位置参量列表 1.9、数组 2、输入输出 2.1、输入-read命令 2.2…

Linux命令du详解

目录 du是什么&#xff1f;du 命令的格式常用的选项速查选项详解及例子du [目录/文件]-a-d-h-s-c--timeformatfull-isolong-isoiso -t 或 --thresholdSIZE --excludePATTERN--si-0 或--null--apparent-size-B size 或--block-sizesize-b 或--bytes-k-m-L 或 --dereference-l 或…

C++类和对象基础

目录 类的认识 访问限定符&#xff1a;public(公有)&#xff0c;protected(保护)&#xff0c;private(私有)。 类的两种定义方式: 类的实例化&#xff1a; 封装&#xff1a; 类的对象大小的计算&#xff1a; 类成员函数的this指针&#xff1a; C语言是面向过程的语言&am…

洛谷_P1605 迷宫_python写法

P1605 迷宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) dfs代码&#xff1a; 这道题也是简单的深搜问题&#xff0c;但是要注意地图的原点记得要初始化maps[sx-1][sy-1] 1 n, m, t map(int,input().split()) sx, sy, fx, fy map(int,input().split()) maps [[0 for _ i…

Java反射:深入解析与实战应用

在Java编程的世界中&#xff0c;反射机制是一种强大的工具&#xff0c;它允许程序在运行时检查和操作类、接口、字段和方法的信息。通过反射&#xff0c;我们可以实现许多高级功能&#xff0c;如动态代理、框架设计等。本文将深入探讨Java反射的基本概念、使用方法以及在实际项…

APP稳定性测试工具:Monkey

一、Monkey 简介 Monkey 是一款 app 的自动化测试工具&#xff0c;monkey 是猴子的意思&#xff0c;所以从原理上说&#xff0c;它的自动化测试就类似猴子一样在软件上乱敲按键&#xff0c;猴子什么都不懂&#xff0c;就爱捣乱。Monkey 原理也是类似&#xff0c;通过向系统发送…

多模态大语言模型的 (R) 演变:调查

目录 1. Introduction2. 赋予LLMs多模态能力2.1 大型语言模型2.2 视觉编码器2.3 视觉到语言适配器2.4 多模式训练 3. 使用 MLLM 处理视觉任务 连接文本和视觉模式在生成智能中起着至关重要的作用。因此&#xff0c;受大型语言模型成功的启发&#xff0c;大量研究工作致力于多模…

Jmeter接口测试步骤

一、使用工具测试 1、使用Jmeter对接口测试 首先我们说一下为什么用Posman测试后我们还要用Jmeter做接口测试&#xff0c;在用posman测试时候会发现的是一个接口一个接口的测试&#xff0c;我们每次测试成功后的数据&#xff0c;在工具中是无法保存的&#xff0c;再次测试的时…

STM32CubeMX学习笔记23---FreeRTOS(任务的挂起与恢复)

1、硬件设置 本实验通过freertos创建两个任务来分别控制LED2和LED3的亮灭&#xff0c;需要用到的硬件资源 LED2和LED3指示灯串口 2、STM32CubeMX设置 根据上一章的步骤创建两个任务&#xff1a;STM32CubeMX学习笔记22---FreeRTOS&#xff08;任务创建和删除&#xff09;-CS…

递归方法解决树的遍历问题

二叉树的最大深度 描述&#xff1a;给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 递归法&#xff08;自顶向下&#xff09; 通过递归法&#xff0c;左右子树同时向下递归遍历&#xff0c;直到遍…

大数据开发--02.环境准备

一.准备三台linux虚拟机 1.分别取名node1,node2,node3 2.配置静态ip 这里以node1为例&#xff0c;配置静态ip地址&#xff0c;其他node2.node3一样 配置完成之后别忘记 systemctl restart network 3.在各自的/etc/hosts文件中编辑三个Ip地址 三台都要配置&#xff0c; 4.然…

【百度灵境矩阵实训营】操作指南

【百度灵境矩阵实训营】操作指南 写在最前面提交注意事项比赛参与指南1、创建智能体作品要求 2、提交作品 学习资料包 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&…

Java SE入门及基础(44)

目录 I / O流(上) 1. 什么是I / O流 过程分析 I / O的来源 Java 中的 I / O流 2. 字节流 OutputStream 常用方法 文件输出流 FileOutputStream 构造方法 示例 InputStream 常用方法 文件输入流 FileInputStream 构造方法 示例 综合练习 字节流应用场景 Java SE文…

LC串联谐振拓扑仿真建模及控制策略分析

直流高压电源主要应用于高端精密分析仪器、高端医疗分析仪器、静电应用、激光雷达、核探测、惯性导航、雷达通信、电子对抗、高功率脉冲、等离子体推进等行业领域。 LC串联谐振拓扑是直流高压电源中最为常用的拓扑结构。上一期内容中我们对 LC 串联谐振变换器的工作原理进行了…