【设计模式】组合模式

news2024/11/24 13:34:38

文章目录

  • 1.组合模式定义
  • 2.组合模式的结构
    • 2.1. 安全式组合模式的结构
    • 2.2.透明式组合模式的结构
  • 3.组合模式实战案例
    • 3.1.场景说明
    • 3.2.关系类图
    • 3.3.代码实现
  • 4.组合模式优缺点
  • 5.组合模式适用场景
  • 6.组合模式总结

在这里插入图片描述

主页传送门:💁 传送

1.组合模式定义

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

Compose objects into tree structure to represent part-whole hierarchies.Composite lets client treat individual objects and compositions of objects uniformly.

       即:将对象组合成树形结构以表示 “部分-整体” 的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

2.组合模式的结构

组合模式的实现根据所实现接口的区别分为两种形式,分别称为安全式和透明式。

2.1. 安全式组合模式的结构

安全模式的组合模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。
在这里插入图片描述
  这种形式涉及到三个角色:

  • 抽象构件(Component)角色: 这是一个抽象角色,它给参加组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。合成对象通常把它所包含的子对象当做类型为Component的对象。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。

  • 树叶构件(Leaf)角色: 树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。

  • 树枝构件(Composite)角色: 代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add()、remove()以及getChild()。

安全式组合模式的缺点是不够透明,因为树叶类和树枝类将具有不同的接口。

2.2.透明式组合模式的结构

与安全式的组合模式不同的是,透明式的组合模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口。
在这里插入图片描述

3.组合模式实战案例

3.1.场景说明

       设计一个文件系统的杀毒软件,文件系统可以分为文件夹和文件,文件又分为文本文件,图片文件,视频文件。

3.2.关系类图

       使用组合模式来实现的结构图如下:
在这里插入图片描述

3.3.代码实现

//Component 抽象构件

/**
 * 抽象文件类:抽象构件接口
 */
interface File {
    /**
     * 默认方法
     * @param file
     */
    public default void add(File file) {
        throw new RuntimeException("reject");
    }
    public default void remove(File file) {
        throw new RuntimeException("reject");
    }
    public default File getChild(int index) {
        throw new RuntimeException("reject");
    }
    void killVirus();
}

//Leaf 叶子构件

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 图像文件类:叶子构建
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class ImageFile implements File {

    private String name;

    @Override
    public void killVirus() {
        System.out.println("---对图像文件:" + name + "正在杀毒!");
    }
}

/**
 * 文本文件类:叶子构件
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class TextFile implements File {
    private String name;

    @Override
    public void killVirus() {
        System.out.println("---对文本文件:" + name + "正在杀毒!");
    }
}

/**
 * 视频文件类:叶子构建
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
class VideoFile implements File {
    private String name;

    @Override
    public void killVirus() {
        System.out.println("---对视频文件:" + name + "正在杀毒!");
    }
}

//Composite 容器构件

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

/**
 * 文件夹类:容器构件
 */
class Folder implements File {

    /**
     * 存储File类型的成员
     */
    private List<File> fileList = new ArrayList<>();
    private String name;

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

    @Override
    public void add(File file) {
        this.fileList.add(file);
    }

    @Override
    public void remove(File file) {
        this.fileList.remove(file);
    }

    @Override
    public File getChild(int index) {
        return this.fileList.get(index);
    }

    @Override
    public void killVirus() {
        System.out.println("---对文件夹:" + name + "进行杀毒!");
        for (File file : fileList) {
            file.killVirus();
        }
    }
}

// 场景类

/**
 * 组合模式案例
 * @author Liucheng
 * @since 2019-07-26
 */
public class Client {

    public static void main(String[] args) {

        File folder1 = new Folder("Sunny的资料");
        File folder2 = new Folder("图像文件");
        File folder3 = new Folder("文本文件");
        File folder4 = new Folder("视频文件");

        File file1 = new ImageFile("小龙女.jpg");
        File file2 = new ImageFile("张无忌.gif");
        File file3 = new TextFile("九阴真经.txt");
        File file4 = new TextFile("葵花宝典.doc");
        File file5 = new VideoFile("笑傲江湖.rmvb");

        folder2.add(file1);
        folder2.add(file2);
        folder3.add(file3);
        folder3.add(file4);
        folder4.add(file5);
        folder1.add(folder2);
        folder1.add(folder3);
        folder1.add(folder4);

        //从“Sunny的资料”节点开始进行杀毒操作
        folder1.killVirus();
    }
}

4.组合模式优缺点

组合模式是一种结构型设计模式,它允许将对象组合成树状的层次结构,以表示“整体-部分”的关系。组合模式的优点和缺点如下:

优点:

  • 简化客户端代码:组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象还是组合对象,这简化了客户端代码。
  • 更容易添加新对象:在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,这符合“开闭原则”。

缺点:

  • 设计较复杂:客户端需要花更多时间理清类之间的层次关系。
  • 不容易限制容器中的构件:不容易用继承的方法来增加构件的新功能。

5.组合模式适用场景

组合模式适用于以下场景:

  1. 表示递归结构:组合模式适合用于表示树形或递归结构,例如文件系统、组织结构等,这些场景中需要对单个对象和组合对象进行一致处理。
  2. 客户端希望忽略差异:当客户端希望忽略组合对象与单个对象的差异时,可以使用组合模式,例如,客户端只需要对整个层次结构进行控制,而不关心具体的单个对象。
  3. 处理树形结构:组合模式适用于处理树形结构,需要对层次进行定义、忽略层次差异、简化客户端代码等。

总之,组合模式适用于处理树形结构或递归结构的场景,当客户端希望忽略差异、简化代码或符合开闭原则时,可以选择使用组合模式。同时需要注意其缺点,如设计复杂、不容易限制容器中的构件等。

6.组合模式总结

     组合模式是一种设计模式,旨在将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端代码以一致的方式处理对象和对象容器,无需关心处理的单个对象还是组合的对象容器。
     总之,组合模式是一种有用的设计模式,可以在适当的情况下应用来简化客户端代码、降低耦合度和提高可扩展性。然而,它也有一些缺点和适用场景需要注意和考虑。

如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论
你的支持就是我✍️创作的动力! 💞💞💞

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

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

相关文章

Spring面试题8:面试官:说一说Spring的BeanFactory

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring的BeanFactory Spring的BeanFactory是Spring框架的核心容器,负责管理和创建Bean对象。它是一个工厂类,用于实例化、配置和管理Bean的…

忽视日志吃大亏,手把手教你玩转 SpringBoot 日志

一、日志重要吗 程序中的日志重要吗&#xff1f; 在回答这个问题前&#xff0c;笔者先说个事例&#xff1a; ❝ 笔者印象尤深的就是去年某个同事&#xff0c;收到了客户反馈的紧急bug。尽管申请到了日志文件&#xff0c;但因为很多关键步骤没有打印日志&#xff0c;导致排查进…

基于springboot+vue的车辆管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

专业排版软件InDesign 2023下载 InDesign mac中文功能

InDesign 2023 mac是一款专业排版软件&#xff0c;适用于Windows和macOS平台。它可以帮助用户创建、设计和排版各种印刷品和数字出版物&#xff0c;如杂志、书籍、报纸、广告、海报、手册、电子书等。 InDesign 2023 mac软件特点 多种页面布局&#xff1a;支持多种页面布局&…

名义实际GDP-各地区-原始和结果(2000-2022年)

一、数据介绍 数据名称&#xff1a;名义、实际GDP-各地区-原始和结果 数据年份&#xff1a;2000-2022年 计算公式&#xff1a;实际GDP 名义GDP / GDP折算指数 数据基期&#xff1a;2000年 数据整理&#xff1a;自主整理 二、数据用途 数据用途 文献依据 经济发展水平 …

如何在.NET电子表格应用程序中创建流程图

前言 流程图是一种常用的图形化工具&#xff0c;用于展示过程中事件、决策和操作的顺序和关系。它通过使用不同形状的图标和箭头线条&#xff0c;将任务和步骤按照特定的顺序连接起来&#xff0c;以便清晰地表示一个过程的执行流程。 在企业环境中&#xff0c;高管和经理利用…

区间重叠问题

区间未重叠数量计算&#xff1a; class Solution {public int findMinArrowShots(int[][] points) {//需要用第一种比较器&#xff1f;第二种会报错&#xff0c;在涉及数的大小边界的时候Arrays.sort(points,(a, b) -> Integer.compare(a[0], b[0]));//(a, b) -> Intege…

【算法思想-排序】根据另一个数组次序排序 - 力扣 1122 题

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

员工执行力差,80%是领导的问题

作者| Mr.K 编辑| Emma 来源| 技术领导力(ID&#xff1a;jishulingdaoli) 读者小T是大厂P7&#xff0c;今年跳到一家行业独角兽公司&#xff0c;做项目经理。没想到&#xff0c;半年后他的领导Y总&#xff0c;在考核中给他的绩效打了D&#xff0c;主要原因是小T“项目按时完成…

大模型分布式训练策略:ZeRO、FSDP

文章目录 一、ZeRO&#xff08;零冗余优化器&#xff09;1.1 背景1.2 深度学习内存消耗分析1.3 主要方法1.3.1 ZeRO-DP优化模型状态内存1.3.2 ZeRO-R优化残余状态内存 1.4 总结1.5 官方视频&#xff1a;ZeRO & Fastest BERT&#xff0c;提高 DeepSpeed 深度学习训练的规模和…

ROS 基础教程

欢迎访问我的博客首页。 ROS 基础教程 1.urdf 文件1.1 在 Rviz 中显示 urdf1.1.1 定义 urdf1.1.2 在 Rviz 中查看 urdf 1.2 在 Gazebo 中显示 urdf1.2.1 定义 urdf1.2.2 在 Gazebo 中查看 urdf 2.建图-仿真2.1 模型 1.urdf 文件 假设我们的工作空间是 ws_ros。我们自己实现的包…

10路LED驱动器和GPIO控制器禾润HTR3310

供电范围&#xff1a;2.5V~5.5V 10个多功能IO&#xff0c;支持LED驱动或GPIO&#xff08;电流源调光&#xff09; LED模式下具有256阶线性调光 任意IO可配置为独立的输入或输出 中断功能&#xff0c;8μs防抖&#xff0c;低电平有效 标准I2C接口&#xff0c;4个I2C器件地址…

AB包的依赖关系

1、什么是依赖关系 有时候一个模型所需要的东西可能在不同的包里面&#xff0c;例如蓝色立方体的模型和材质在不同的包&#xff08;mode和head&#xff09;里&#xff0c;这时需要加载两个包才能让这个球正常显示 2、如何获取依赖关系并加载 //加载AB包 AssetBundle ab Asse…

a single dex file (# methods: 67938 > 65536)

问题 项目不大&#xff0c;但是导入的包比较多&#xff0c;导致方法数量超过了一定数量 Cannot fit requested classes in a single dex file (# methods: 67938 > 65536) Android 5.0之前的版本&#xff08;API level < 21&#xff09;使用Dalvik runtime来执行代码&a…

服务器搭建(TCP套接字)-epoll版(服务端)

epoll 是一种在 Linux 系统上用于高效事件驱动编程的 I/O 多路复用机制。它相比于传统的 select 和 poll 函数具有更好的性能和扩展性。 epoll 的主要特点和原理&#xff1a; 1、事件驱动&#xff1a;epoll 是基于事件驱动的模型&#xff0c;它通过监听事件来触发相应的回调函…

七分钟,数据转换器get到了

全文阅读时间 | 预计七分钟 KING BASE 开源 OR 闭源&#xff1f; 在瞬息多变的软件市场上&#xff0c;开源还是闭源是一个恒久不变的话题。开源软件得益于基础架构和基本功能的全面开放&#xff0c;开发者能自由使用和二次开发&#xff0c;但使用前提是需要投入大量成本对软件进…

centos 7.9系统安装向日葵

1.下载地址 向日葵远程控制app官方下载 - 贝锐向日葵官网 2.下载依赖 yum install -y libappindicator-gtk3 安装好依赖之后&#xff0c;然后再安装向日葵软件 3.安装软件 sudo rpm -ivh 文件名.rpm 4.安装成功之后的位置

【Android Framework系列】第16章 存储访问框架 (SAF)

1 概述 Android 4.4&#xff08;API 级别 19&#xff09;引入了存储访问框架 (Storage Access Framework)。SAF让用户能够在其所有首选文档存储提供程序中方便地浏览并打开文档、图像以及其他文件。 用户可以通过易用的标准 UI&#xff0c;以统一方式在所有应用和提供程序中浏…

【神印王座】龙皓晨竟然上了头版头条!内容违背,新闻真实性原则

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析神印王座国漫。 大家有没有发现&#xff0c;当龙皓晨他们从驱魔关回到圣城时&#xff0c;有这么一幕&#xff0c;一个卖报小孩边走边说&#xff1a;驱魔关大捷&#xff0c;少年英雄龙皓晨操控守护与怜悯之神印王座&#x…

使用Pugixml库,轻松处理XML文件

文章作者&#xff1a;里海 来源网站&#xff1a;王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C-CSDN博客 目录 1.介绍 2.Pugixml库 3.配置Visual Studio开发环境 4.节点 5.常见的节点类型 6.命名空间pugi 7.xml_document装载整个XML文档结构 8.xml_node文…