组合模式(十二)

news2024/11/29 4:53:04

请相信自己,请再次相信自己,请一定要相信自己

上一章简单介绍了装饰者模式(十一), 如果没有看过, 请观看上一章

一. 组合模式

引用 菜鸟教程里面的 组合 模式介绍: https://www.runoob.com/design-pattern/composite-pattern.html

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。

组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,

它创建了对象组的树形结构。

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

一.一 介绍

意图: 将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

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

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

如何解决: 树枝和叶子实现统一接口,树枝内部组合该接口。

关键代码 树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

应用实例 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作数也可以是操作数、操作符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。

优点 1、高层模块调用简单。 2、节点自由增加。

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

使用场景 部分、整体场景,如树形菜单,文件、文件夹的管理。

注意事项 定义时为具体类。

组成角色具体关系作用
ComponentOrgComponent用于访问和管理 Component 子部件用于访问和管理 Component 子部件
LeafZhuanYe叶子节点,没有子节点叶子节点,没有子节点
CompositeDaXue, XueYuan非叶子节点,用于存储子部件非叶子节点,用于存储子部件

image-20230614171304909

二. 组合模式实例

  1. 定义一个 抽象类, 填入基本的属性和方法

  2. 针对抽象类进行实现, 有叶子节点实现 和 非叶子节点实现

叶子节点实现的话, 没有集合的操作

非叶子节点实现的话, 是有集合引用的, 需要针对集合中的每一个操作进行处理。

二.一 定义子元素

@Data
public abstract class OrgComponent {
    private String name;
    private String desc;


    public OrgComponent (String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public void add (OrgComponent orgComponent) {
        throw new UnsupportedOperationException();
    }
    public void remove(OrgComponent orgComponent) {
        throw new UnsupportedOperationException();
    }

    public OrgComponent getChild(int i) {return null;}

    public abstract void print();

}

二.二 叶子节点

@Slf4j
public class ZhuanYe  extends OrgComponent{

    public ZhuanYe(String name, String desc) {
        super(name, desc);
    }

    @Override
    public void print() {
        log.info(">>>>>>>>>>>>>>>>>>>>>>{}",getName());
    }
}

二.三 非叶子节点

二.三.一 大学

@Slf4j
public class DaXue extends OrgComponent{

    private List<OrgComponent> children = new ArrayList<>();

    public DaXue(String name, String desc) {
        super(name, desc);
    }


    @Override
    public void add(OrgComponent orgComponent) {
        children.add(orgComponent);
    }

    @Override
    public void remove(OrgComponent orgComponent) {
        Iterator<OrgComponent> iterator = children.iterator();
        while(iterator.hasNext()) {
            OrgComponent next = iterator.next();
            if (next.getName().equals(orgComponent.getName())) {
                iterator.remove();
            }
        }
    }

    @Override
    public OrgComponent getChild(int i) {
        if (children.size() > i) {
            return children.get(i);
        }else {
            return null;
        }
    }

    @Override
    public void print() {
       if (!CollectionUtil.isEmpty(children)){
           log.info(">{}",getName());
           for (OrgComponent orgComponent : children) {
               orgComponent.print();
           }
       }
    }
}

二.三.二 学院

@Slf4j
public class XueYuan extends OrgComponent{

    private List<OrgComponent> children = new ArrayList<>();

    public XueYuan(String name, String desc) {
        super(name, desc);
    }


    @Override
    public void add(OrgComponent orgComponent) {
        children.add(orgComponent);
    }

    @Override
    public void remove(OrgComponent orgComponent) {
        Iterator<OrgComponent> iterator = children.iterator();
        while(iterator.hasNext()) {
            OrgComponent next = iterator.next();
            if (next.getName().equals(orgComponent.getName())) {
                iterator.remove();
            }
        }
    }
    @Override
    public OrgComponent getChild(int i) {
        if (children.size() > i) {
            return children.get(i);
        }else {
            return null;
        }
    }
    @Override
    public void print() {
       if (!CollectionUtil.isEmpty(children)){
           log.info(">>>>>>>>>>>{}",getName());
           for (OrgComponent orgComponent : children) {
               orgComponent.print();
           }
       }
    }
}

二.四 测试方法

@Test
    public void oneTest() {
        OrgComponent daXue = new DaXue("大学","大学1");

        OrgComponent xueYuan1 = new XueYuan("学院1","学院1");
        OrgComponent xueYuan2 = new XueYuan("学院2","学院2");

        daXue.add(xueYuan1);
        daXue.add(xueYuan2);

        // 添加专业

        OrgComponent zhuanYe1 = new ZhuanYe("专业1","专业1");
        OrgComponent zhuanYe2 = new ZhuanYe("专业2","专业2");
        OrgComponent zhuanYe3 = new ZhuanYe("专业3","专业3");
        OrgComponent zhuanYe4 = new ZhuanYe("专业4","专业4");


        xueYuan1.add(zhuanYe1);
        xueYuan1.add(zhuanYe2);
        xueYuan2.add(zhuanYe3);
        xueYuan2.add(zhuanYe4);

        log.info(">>>>> 移除之前 大学打印: ");
        // 进行打印
        daXue.print();
        log.info(">>>>> 移除之前 学院打印: ");
        xueYuan1.print();

        xueYuan1.remove( zhuanYe1);

        log.info(">>>>> 移除之后打印: ");

        daXue.print();
        xueYuan1.print();


    }

image-20230614171849926

需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式

要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式


本章节的代码放置在 github 上:


https://github.com/yuejianli/DesignPattern/tree/develop/Composite


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

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

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

相关文章

有多少运维配置防火墙忽略了长连接?

长连接的使用场景 当业务中客户端和服务器长时间无数据交互&#xff0c;空闲时间超过1800秒&#xff0c;会话会因超时被清除。后续客户端没有重新发起连接&#xff0c;直接发送控制报文时导致数据不通。常见于数据库连接。 1. 重点说明 以天为单位的会话超时需要开启长效会话比…

Android 进程间通信机制(六) 手写AIDL文件

阅读本篇文章前, 请先查看一下笔者之前的写的两篇博客文章: Android Service知识 和 Android AIDL使用 进程间通信涉及到客户端和服务端, 肯定有绑定服务的过程, 所以要阅读一下Android Service相关的知识, 跨进程通信的媒介aidl文件,我们也必须要了解怎么创建的,有什么规则…

【Jenkins】全网最详细的自动化测试

学习 Jenkins 自动化测试的系列文章 Robot Framework 概念Robot Framework 安装Pycharm Robot Framework 环境搭建Robot Framework 介绍Jenkins 自动化测试 1. Robot Framework 概念 Robot Framework是一个基于Python的&#xff0c;可扩展的关键字驱动的自动化测试框架。 它…

走进人工智能|GANs AI时代下的前卫艺术

前言&#xff1a; GANs的作用是以生成模型的形式学习数据分布&#xff0c;从而产生逼真的样本数据&#xff0c;可以应用于图像合成、风格转换、视频生成等领域。 文章目录 序言背景适用领域技术支持应用领域程序员如何学总结 序言 GANs&#xff08;生成对抗网络&#xff09;是…

测试为什么分白盒、黑盒、单元、集成测试?

一、为什么测试的概念这么多 一个软件项目就好比一部复杂的汽车&#xff0c;有很多零件&#xff0c;当每个零件生产完成后&#xff0c;就要测试零件是否存在质量问题。零件组成复杂的汽车后&#xff0c;我们还要测试汽车。比如著名的中保研&#xff0c;测试刹车&#xff0c;测…

运维圣经:挖矿木马应急响应指南

目录 挖矿木马简介 挖矿流程 挖矿木马应急响应 一. 隔离被感染主机 二. 确定挖矿进程 三. 挖矿木马清除 1、阻断矿池地址的连接 2、清除挖矿定时任务、启动项等 3、禁用可疑用户 4、定位挖矿木马文件的位置并删除 5、全盘杀毒、加固 挖矿木马简介 挖矿&#xff1a;…

喜报|瑞云科技荣获“年度汽车数字化营销供应商”奖

由iDigital China举办&#xff0c;中国国际贸易促进委员会汽车行业分会战略支持的ADMIC汽车数字化&营销创新峰会暨金璨奖颁奖盛典于2023年4月19日在上海圆满落幕。深圳市瑞云科技股份有限公司受邀参会&#xff0c;现场设有展位&#xff0c;为观众展示实时云渲染如何助力汽车…

实现阿里云域名的DDNS

实现阿里云域名的DDNS 目前现状与痛点 我们在使用ddns的时候会不会遇到这样的问题&#xff1a;路由器只支持指定的域名服务提供商或者是指定的域名&#xff0c;比如我的华为路由器就只支持花生壳&#xff1a; 我想看到这篇文章的小伙伴们应该都把域名注册到中国最大的域名注…

Nginx安装与配置

Nginx安装与配置 一、简介二、安装三、功能与配置3.1、正向代理3.2、反向代理3.3、负责均衡3.4、ip_hash3.5、轮询3.6、加权轮询 四、nginx安全相关配置五、常用命令 一、简介 Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。 Ngin…

Windows11 安装 CUDA/cuDNN+Pytorch

一、准备工作&#xff1a; 查看torch版本&#xff1a;进入python交互环境&#xff1a; >>>import torch >>>torch.__version__ 查看cuda版本&#xff1a;CMD窗口 nvcc --version 如果版本不一致&#xff0c;需要卸载再重装。 二、安装 Windows 安装 CU…

【裸机开发】指定外设根时钟配置实验(三)—— 寄存器分析篇(PERCLK_CLK_ROOT、IPG_CLK_ROOT)

前面已经完成了 PLL1 和 8 路 PFD 的初始化&#xff0c;至于其他 PLL 路&#xff0c;等实际需要的时候再初始化也不迟。接下来我们就挑选几个具体的外设时钟进行配置。 假设我们要初始化下面两个根时钟PERCLK_CLK_ROOT、IPG_CLK_ROOT。&#xff08;中途可能还涉及到根时钟 AHB…

【01】如何在电脑上使用wink一键高清短视频

如何在电脑上使用wink一键高清优化短视频画质 文章目录 如何在电脑上使用wink一键高清优化短视频画质1.软件简介1.1痛点1.2解决方案 2.实际操作2.1准备工作2.1.1下载雷电模拟器2.1.2下载wink 2.2.安装软件2.2.1安装雷电模拟器2.2.2安装wink2.2.2.1在雷电模拟器中安装wink2.2.2.…

【操作系统】计算机操作系统知识点总结

文章目录 前言一、操作系统的概念与发展二、操作系统的结构与功能1、操作系统的结构2、操作系统的功能 三、进程管理1、进程2、进程的创建3、进程管理的实现4、进程控制块 四、内存管理1、内存2、内存管理3、内存管理的实现 五、文件系统1、文件系统2、文件系统的主要任务3、文…

微服务springcloud 03.Eureka实现高可用

01.运行时候项目图存在两个item service&#xff0c;和两个Eureka注册中心 02.在已有的项目中扩展service服务数量&#xff08;item service的数量变成两个&#xff09; 第一步&#xff1a;配置item service的启动参数 启动参数的优先级要高于yml文件的优先级 具体参数是&#…

两万字深入浅出yolov5+deepsort实现目标跟踪,含完整代码, yolov,卡尔曼滤波估计,ReID目标重识别,匈牙利匹配KM算法匹配

目录 一&#xff1a;前言 二&#xff1a;跟踪部分&#xff1a; ReID结构​编辑 第一帧&#xff08;生成track&#xff09; 第二帧 更新先验的预测值 状态矩阵的初始化 对预测值进行更新&#xff08;矫正&#xff09;&#xff1a; 匹配完成&#xff0c;进行矫正的更新&…

CSC改派+延期|影像学医生赴英国伦敦国王学院从事访学研究

因美国拒签&#xff0c;又临近派出截止期限。为避免出国指标作废&#xff0c;Q医生希望获得英国高校的邀请函&#xff0c;以申请CSC的改派并延期。我们为其落实了世界名校-英国伦敦国王学院访问学者职位&#xff0c;导师的研究方向属前沿热点&#xff0c;具有广阔的发展前景。Q…

C++【二叉树进阶试题】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C/C相关题解 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 606. 根据二叉树创建字符串102. 二叉树的层序遍历107. 二叉树的层序遍历 II236. 二叉树的最近公共祖先JZ36 二叉搜…

位姿估计 | 从目标特征点检测到目标体坐标系相对于相机坐标系的位姿估计过程

目录 引言技术流程1. PNP介绍2. ICP介绍a. 利用ICP求解目标相对相机的位姿b. 利用ICP求解相机帧间运动 引言 本文接着分享空间目标位姿跟踪和滤波算法中用到的一些常用内容&#xff0c;希望为后来者减少一些基础性内容的工作时间。以往分享总结见文章&#xff1a;位姿跟踪 | 相…

当你全力以赴世界也会为你让路,23级人大女王金融硕士准备中

当你全力以赴&#xff0c;世界也会为你让路&#xff0c;在申报人民大学与加拿大女王大学金融硕士&#xff08;国际班&#xff09;项目的路上你真的努力了吗&#xff1f; 记得曾经在知乎上看过一个问题“什么事情给你的生活带来什么改变”&#xff0c;下边有很多人回答说&#x…

【每日算法】【202. 快乐数】

☀️博客主页&#xff1a;CSDN博客主页 &#x1f4a8;本文由 我是小狼君 原创&#xff0c;首发于 CSDN&#x1f4a2; &#x1f525;学习专栏推荐&#xff1a;面试汇总 ❗️游戏框架专栏推荐&#xff1a;游戏实用框架专栏 ⛅️点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd;&…