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

news2024/11/22 19:38:21

一、组合模式

概述

组合模式(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. 使用场景

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

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

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

相关文章

【YUNBEE云贝-PostgreSQL】FDW应用

注: 本文为云贝教育 刘峰 原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 前言 Wrapper&#xff08;FDW&#xff09;是一项关键特性&#xff0c;它赋予数据库用户直接通过SQL语句访问存储于外部数据源的能…

Jumpserver 堡垒机用户启用双因子登录

前言&#xff1a; 堡垒机双因子登录 堡垒机往往是内部权限的集合体&#xff0c;拿到了堡垒机的用户账号密码&#xff0c;很容易就顺藤摸瓜攻破各种应用系统&#xff0c;除了常规的用户名复杂密码的要求外&#xff0c;我们常常都要求采用双因子的登录方式。双因子最常见的就是账…

【Super数据结构】先进先出/后进先出,队列和栈代码实现+应用场景

&#x1f3e0;关于此专栏&#xff1a;Super数据结构专栏将使用C/C语言介绍顺序表、链表、栈、队列等数据结构&#xff0c;每篇博文会使用尽可能多的代码片段图片的方式。 &#x1f6aa;归属专栏&#xff1a;Super数据结构 &#x1f3af;每日努力一点点&#xff0c;技术累计看得…

HarmonyOS如何使用低代码实现界面布局

介绍 本篇Codelab是基于ArkTS语言的低代码开发方式实现的一个简单实例。具体实现功能如下&#xff1a; 创建一个低代码工程。通过拖拽的方式实现任务列表和任务信息界面的界面布局。在UI编辑界面实现数据动态渲染和事件的绑定。 最终实现效果如下&#xff1a; 相关概念 低代…

ECharts5 概念篇2

数据转换 数据转换基础使用 在 echarts 中&#xff0c;数据转换是依托于数据集&#xff08;dataset&#xff09;来实现的. 我们可以设置 dataset.transform 来表示&#xff0c;此 dataset 的数据&#xff0c;来自于此 transform 的结果。下面是上述例子的效果&#xff0c;三个饼…

冶炼金属(二分)

题目描述&#xff1a; 小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。 这个炉子有一个称作转换率的属性 V&#xff0c;V是一个正整数&#xff0c;这意味着消耗 V个普通金属 O 恰好可以冶炼出一个特殊金属 X&#xff0c;当普通金属 O 的数目不足 V 时&#x…

【机器学习】基于粒子群算法优化的BP神经网络分类预测(PSO-BP)

目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】粒子群算法&#xff08;PSO&#xff09;原理及实现 2.设计与实现 数据集&#xff1a; 多输入多输出&#xff1a;样本特征24&#xff0c;标签类别4…

项目五 实现对学生信息的简单查询

项目五 实现对学生信息的简单查询 1&#xff0c;查询数据库中部分字段的信息 使用select语句对表的选择及连接等操作&#xff0c;结构会生成一个临时表&#xff0c;将select结果存放到临时表中 查询数据表中所有字段的值 #格式&#xff1a;(*:表示所有列) select * from 表…

milvus安装

milvus安装 sudo curl -L “https://github.com/docker/compose/releases/download/1.29.2/docker-compose- $ (uname -s)- $ (uname -m)” -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/…

SpringBoot项目通过触发器调度实现定时任务

文章目录 前言一、quartz是什么&#xff1f;二、quartz中核心概念三、集成步骤1.引入依赖2.demo样例a.定义一个任务参数实体类b.定义操作触发器、定时任务接口及实现c.作业实现d.结果截图 四、其他1.QuartzJobBean和Job区别2.注意事项3.作业&#xff08;Job&#xff09;和触发器…

考虑功率均分与电压频率的事件触发分布式二次控制MATLAB模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 此模型是在《基于事件触发机制的孤岛微电网二次电压与频率协同控制MATLAB仿真模型》上进一步创作的&#xff0c;之前的模型只考虑了二次电压与频率控制&#xff0c;并没有考虑均分这一项点。 因此…

STM32相关资料汇总

STM32选型表 STM32手册参考网站 https://www.stmcu.org.cn/

文件包含漏洞之包含NGINX日志文件(常用)

条件&#xff1a;知道目标服务器的日志文件存贮路径&#xff0c;并且存在文件包含漏洞 首先对目标服务器发送一次含有木马的请求&#xff0c;目的是让目标服务器日志中生成含有木马的日志记录。因为发送过程中&#xff0c;使用了url编码&#xff0c;我们抓包进行更改成能够执行…

网络——入门基础

目录 协议 网络协议 OSI七层模型 网络传输基本流程 网络传输流程图 局域网通信 数据包的封装和解包 广域网通信 网络地址管理 IP地址 MAC地址 协议 关于什么是局域网&#xff0c;什么是广域网&#xff0c;我这里就不过多赘述了&#xff0c;我们直接来谈一下什么…

复旦发布层次性奖励学习框架,增强大模型人类偏好对齐

在人工智能领域&#xff0c;强化学习&#xff08;Reinforcement Learning, RL&#xff09;一直是实现智能体自主学习的关键技术之一。通过与环境的交互&#xff0c;智能体能够自我优化其行为策略&#xff0c;以获得更多的奖励。然而&#xff0c;当涉及到复杂的人类偏好时&#…

codeforces 1600分

文章目录 1.[G. Special Permutation](https://codeforces.com/problemset/problem/1352/G)2.[D. Constructing the Array](https://codeforces.com/problemset/problem/1353/D)3.[C2. k-LCM (hard version)](https://codeforces.com/problemset/problem/1497/C2)4.[C. Circle …

【ollama】linux、window系统更改模型存放位置,全网首发2024!

首先是window系统 so easy 直接进入系统环境变量添加就行 其次是linux系统 全靠自己试出来的&#xff0c;去Ollama官网找半天文档不知道在哪&#xff0c;而且linux也没有说&#xff1a;【 https://github.com/ollama/ollama/blob/main/docs/README.md https://github.com/o…

CSS Module

CSS Module的作用&#xff1a;将CSS样式作用域限制在特定的组件范围内&#xff0c;以避免全局样式污染和命名冲突。 Vue中如何实现样式模块…

一款博客网站源码

一款博客网站源码 源码软件库 为大家内置了主题 清爽又强大真正的永久可用的一条源码&#xff0c;该版本为整合版本&#xff0c;内置了Joe主题&#xff0c;搭建后直接启用即可~ 安装环境要求&#xff1a; PHP 7.2 以上 MySQL, PostgreSQL, SQLite 任意一种数据库支持&#xff…

BUUCTF-WEB1

[ACTF2020 新生赛]Exec1 1.打开靶机 是一个ping命令 2.利用管道符“|” ping一下本地主机并查看ls ping 127.0.0.1 | ls 可以看到回显的内容是一个文件 127.0.0.1 | cat index.php #查看主机下index.php 127.0.0.1 | ls / #查看主机根目录下的文件 看的一个flag文件 …