秒懂设计模式--学习笔记(8)【结构型-组合模式】

目录

      • 7、组合模式
          • 7.1 组合模式(Composite)
          • 7.2 叉树结构
          • 7.3 文件系统
          • 7.4 目录树展示
          • 7.5 自相似性的涌现
          • 7.6 组合模式的各角色定义
          • 7.7 组合

7、组合模式

7.1 组合模式(Composite)
  • 是针对由多个节点对象(部分)组成的树形结构的对象(整体)而发展出的一种结构型设计模式
  • 它能够使客户端在操作整体对象或者其下的每个节点对象时做出统一的响应,保证树形结构对象使用方法的一致性
  • 整体和部分,有类似结构
  • 测试类结构
    组合模式测试类
7.2 叉树结构
  • 某些具有从属关系的事物之间存在着一定的相似性
  • 不管从哪个层级,我们都会得到一个固定的结构
  • 这种结构类似于经典的“叉树”结构:无论数据元素是“根”“枝”,还是“叶”,甚至是整体的树,都具有类似的结构
  • 我们可以用组合模式来表达“部分/整体”的层次结构提取并抽象其相同的部分特殊化其不同的部分,以提高系统的可复用性与可扩展性
7.3 文件系统
  • 以类似于树结构的文件系统的目录结构为例
  • 抽象节点类Node
    • 定义一个抽象的“节点”类来模糊“文件夹”与“文件”
    • 构造方法中接收并初始化已定义的节点名,否则不允许节点被创建,这也是可以固化下来的逻辑
    • 声明抽象方法,模糊行为并留给子类去实现
package composite;/*** 抽象节点类**/
public abstract class Node {// 节点命名protected  String name;/*** 构造方法,需传入节点名*  构造方法中接收并初始化已定义的节点名,否则不允许节点被创建,这也是可以【固化下来的逻辑】*/public Node(String name) {this.name = name;}/*** 添加下级节点方法: 声明其为抽象方法,模糊此行为并留给子类去实现* @param child*/protected abstract void add(Node child) throws Exception;
}
  • 节点实现类1:文件夹类Folder
    • 文件夹类继承了抽象节点类Node
    • 文件夹下级可以包含任意多个文件夹或者文件:次级节点列表List
package composite;import java.util.ArrayList;
import java.util.List;/*** 文件夹类:继承了抽象节点类Node**/
public class Folder extends Node {/*** 文件夹可以包含子节点(子文件夹或文件)*  此处的泛型Node既可以是文件夹又可以是文件*/List<Node> children = new ArrayList<>();/*** 调用父类构造方法:初始化其文件夹名* @param name*/public Folder(String name) {super(name);}/*** 重写添加方法:可以添加子节点* @param child*/@Overrideprotected void add(Node child) {children.add(child);}
}
  • 节点实现类2:文件类File
    • 其作为末端节点,不应该具备添加子节点的功能
package composite;/*** 文件类:继承了抽象节点类Node**/
public class File extends Node {/*** 调用父类构造方法:初始化其文件夹名* @param name*/public File(String name) {super(name);}/*** 文件不包含子节点: 告知用户“不能添加子节点”* 其实更好的方式是以抛出异常的形式来确保此处逻辑的正确性,外部如果捕获到该异常则可以做出相应的处理* @param child*/@Overrideprotected void add(Node child) {System.out.println("文件类型不能添加子节点");}
}
  • 客户端测试类:创建文件夹及文件
package composite;/*** 客户端测试类**/
public class Client {public static void main(String[] args) throws Exception {// 为根节点构建了目录树Node driveD = new Folder("测试盘");// “文档”和“音乐”两个文件夹Node doc = new Folder("文档");doc.add(new File("简历.doc"));doc.add(new File("项目介绍.ppt"));driveD.add(doc);// “文档”和“音乐”两个文件夹Node music = new Folder("音乐");// 一级文件夹来区分歌手Node jay = new Folder("周杰伦");jay.add(new File("双截棍.mp3"));jay.add(new File("告白气球.mp3"));jay.add(new File("听妈妈的话.mp3"));// 一级文件夹来区分歌手Node jack = new Folder("张学友");jack.add(new File("吻别.mp3"));jack.add(new File("一千个伤心的理由.mp3"));music.add(jay);music.add(jack);driveD.add(music);}
}
7.4 目录树展示
  • 要体现出组合模式的优势还在于如何运用这个树结构
  • 分级展示整棵目录树
    • 输出节点名称(文件夹名/文件名)之前加上数个空格以表示不同层级
    • 修改抽象节点类Node并加入展示方法tree()
        /*** 此处是抽象节点类的实体方法,所以要保持其通用性。*      我们抽离出所有节点“相同”的部分作为“公有”的代码块,*      而“不同”的行为部分则留给子类去实现* @param space 空格数(层级缩进展示)*/protected void  tree(int space) {//先循环输出space个空格for (int i = 0; i < space; i++) {System.out.print("    ");}//接着再输出自己的名字System.out.println(name);}/*** 无参重载方法,默认从第0列开始展示(无层级缩进)*/protected void tree() {this.tree(0);}
    
    • 节点实现类File和Folder重写展示方法,Folder还要展示其子级
        /*** Folder* 文件夹类就比较特殊了,它不仅要先输出自己的名字,还要换行再逐个输出子节点的名字,并且要保证空格逐级递增*/@Overridepublic void tree(int space) {// 调用父类通用的tree方法列出自己的名字super.tree(space);// 在循环的子节点前,空格数要加1space++;// 下一级的子节点我们需要依次输出for (Node child : children) {// 调用子节点的tree方法child.tree(space);}}
    
    /*** File* 文件类可以不做任何修改,而是直接继承父类的展示方法,* 此处是为了更清晰直观地看到这种继承关系,同时方便后续做出其他修改* @param space*/
    @Override
    public void tree(int space){super.tree(space);
    }
    
    • 客户端在任何一级节点上只要调用其展示方法并传入当前目录所需的空格偏移量,就可出现树形列表了
    	// Client类的main方法最后添加调用目录树展示方法driveD.tree();
    
    • 空格偏移量这个必传参数,可以为抽象节点类添加一个无参的展示方法,默认为0
7.5 自相似性的涌现
  • 组合模式将树形结构的特点发挥得淋漓尽致
    • 作为最高层级抽象的抽象节点类(接口)泛化了所有节点类使任何“整体”或“部分”达成统一
    • 枝(根)节点与叶节点的多态化实现以及组合关系进一步勾勒出的树形结构
7.6 组合模式的各角色定义
  • Component(组件接口):
    • 所有复合节点与叶节点的高层抽象,定义出需要对组件操作的接口标准
    • 如抽象节点类Node,具体使用接口还是抽象类需根据具体场景而定。
  • Composite(复合组件):
    • 包含多个子组件对象(可以是复合组件或叶端组件)的复合型组件,并实现组件接口中定义的操作方法。
    • 如:“根节点/枝节点”的文件夹类Folder
  • Leaf(叶端组件):
    • 不包含子组件的终端组件,同样实现组件接口中定义的操作方法。
    • 如: “叶节点”的文件类File
  • Client(客户端):
    • 按所需的层级关系部署相关对象并操作组件接口所定义的接口,即可遍历树结构上的所有组件
7.7 组合
  • 类似的结构总是在重复、迭代地显现出某种自似性
  • 其部分与整体一致的呈现与“组合模式”如出一辙

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

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

相关文章

关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论

目录 问题一&#xff1a;关于string的\0问题讨论 问题二&#xff1a;C标准库中的string内存是分配在堆上面吗&#xff1f; 问题三&#xff1a;string与vector的capacity大小设计的特点 问题四&#xff1a;string的流提取问题 问题五&#xff1a;迭代器失效 问题六&#xf…

个人开发实现AI套壳网站快速搭建(Vue+elementUI+SpringBoot)

目录 一、效果展示 二、项目概述 三、手把手快速搭建实现本项目 3.1 前端实现 3.2 后端方向 五、后续开发计划 一、效果展示 默认展示 一般对话展示&#xff1a; 代码对话展示&#xff1a; 二、项目概述 本项目是一个基于Web的智能对话服务平台&#xff0c;通过后端与第…

【C语言】指针(4):深入理解指针

目录 ​编辑 一、回调函数 二、qsort使用举例 2.1 使用qsort排序整型数据 2.2 使用qsort排序结构体数据 三、qsort的模拟实现 四、NULL、\0、0、0、null、NUL的区别 五、C99中的变长数组 一、回调函数 函数指针是将函数的地址取出来&#xff0c;再通过函数地址去调用&a…

untiy 在菜单栏添加自定义按钮 点击按钮弹出一个Unity窗口,并在窗口里添加属性

using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Rendering.PostProcessing;public class AutoGenerateWindow : EditorWindow //这是定义一个窗口 {public string subjecttName "科目名字";//科目的名字public GameOb…

url链接地址,#前的参数 和 #后的参数有什么区别

例如 http://localhost:8080/?beforeParams1#/workSchemelist/index?afterParams1 beforeParams 和 afterParams 区别 打印出来可以发现&#xff1a; beforeParams 是 url 的search参数&#xff0c;通过window.location.search获取 afterParams 是 route 的query参数&#…

外贸网站设计的要点

外贸网站设计是一种专门针对国际贸易领域的网站设计&#xff0c;需要考虑到不同国家和文化背景的用户&#xff0c;因此设计过程要更加细致和精准。以下是外贸网站设计的关键要点&#xff1a; 首先&#xff0c;多语言支持是不可或缺的&#xff0c;因为外贸网站的用户可能来自不同…

[Python自动化办公]--从网页登录网易邮箱进行邮件搜索并下载邮件附件

[Python自动化办公]–从网页登录网易邮箱进行邮件搜索并下载邮件附件 使用说明 ​ 本文使用Python的selenium库进行操作邮箱登录、固定名称搜索邮件并下载附件&#xff0c;Python版本&#xff1a;3.9.16, selenium版本&#xff1a;4.19.0&#xff0c;EdgeBrowser版本:126.0.2…

LVS集群及其它的NAT模式

1.lvs集群作用&#xff1a;是linux的内核层面实现负载均衡的软件&#xff1b;将多个后端服务器组成一个高可用、高性能的服务器的集群&#xff0c;通过负载均衡的算法将客户端的请求分发到后端的服务器上&#xff0c;通过这种方式实现高可用和负载均衡。 2.集群和分布式&#…

用户增长 - 私域 - 社群运营自检清单SOP(社群运营30问)

Check List: 1.你的目标用户是谁&#xff1f; 2.你的目标用户有哪些需要立马解决的需求&#xff1f;有哪些长期需求&#xff1f;这些需求的优先级是什么&#xff1f; 3.做社群的目的是什么&#xff1f; 4.你的用户和业务是否适合做社群&#xff1f; 5.你做哪类社群才能更好的帮…

确定适合您需求的负载组

大多数关键任务行业都使用 UPS 和发电机等备用电源在停电期间为其设施提供持续电力。负载组允许您在需要时测试电源&#xff0c;以确保在您最需要的时候提供可靠的电力。 选择正确的负载组对于准确的电源测试至关重要。为了帮助您找到最适合您设施需求的负载组&#xff0c;EAK…

【机器学习】主成分分析(PCA):数据降维的艺术

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 主成分分析&#xff08;PCA&#xff09;&#xff1a;数据降维的艺术引言PCA的基…

技术成神之路:设计模式(四)工厂方法模式

1.定义 工厂方法模式&#xff08;Factory Method Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的接口&#xff0c;而不是通过具体类来实例化对象。工厂方法模式的主要作用是让子类决定实例化哪一个类&#xff0c;从而实现对象创建的延迟到具体子类…

2024年6月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2024年6月国产数据库大事件和重要产品发布消息。 目录 2024年6月国产数据库大事记 TOP102024年6月国产数据库大事记&#xff08;时间线&#xff09;产品/版本发布兼容认证代表厂商大事记厂商活动相关资料 2024年6月国产数据库大事记 TOP10 2024年6月国…

【Python】已解决:SyntaxError invalid syntax

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;SyntaxError invalid syntax 一、分析问题背景 在Python编程中&#xff0c;SyntaxError: invalid syntax是一个常见的错误&#xff0c;它通常表示代码中存在语法…

案例|水上水下一体化测量,为九寨沟精准把脉

​ 九寨沟&#xff0c;被誉为“人间仙境”&#xff0c;其湖群以独特的地理位置和优美的自然景观吸引着世界各地的游客&#xff0c;更是九寨沟生态系统中不可或缺的重要组成部分。因此&#xff0c;精准地掌握湖群的地形数据、水体分布及变化情况&#xff0c;能够揭示水下生态系…

【数据结构与算法基础】算法复杂度

欢迎光顾我的homepage 前言 算法就是定义良好的计算过程&#xff0c;它取一个活一组的值输入&#xff0c;并产生出一个或一组值作为输出。简单来说&#xff0c;算法就是一系列的计算步骤&#xff0c;用来将输入数据转化成输出结果。 一、算法效率 如何去衡量一个算法的好坏&am…

[C++]——同步异步日志系统(3)

同步异步日志系统 一、日志系统框架设计1.1模块划分1.1.1 日志等级模块1.1.2 日志消息模块1.1.3 日志消息格式化模块1.1.4 日志落地模块&#xff08;日志落地的方向是工厂模式&#xff09;1.1.5 日志器模块&#xff08;日志器的生成是建造者模式&#xff09;1.1.6 异步线程模块…

强化学习总结(有具体代码实现)

文章目录 第一部分 强化学习基础第1章 强化学习概述1.1 强化学习概念1.2 强化学习的环境1.3 强化学习的目标1.4 强化学习的数据 第2章 多臂老虎机问题&#xff08;MAB问题&#xff09;2.1 问题描述2.1.1 问题定义2.1.2 形式化描述2.1.3 累积懊悔2.1.4 估计期望奖励 2.2 解决方法…

【机器学习】必会数学知识:一文掌握数据科学核心数学知识点(上),值得收藏~

核心数学知识点 1、引言2、数据科学必会数学知识2.1 线性代数2.2 微积分2.3 概率论2.4 数理统计2.5 随机过程2.6 数据分布2.7 贝叶斯统计2.8 线性回归2.9 逻辑回归2.10 矩阵分解2.11 主成分分析&#xff08;PCA&#xff09;2.12 奇异值分解&#xff08;SVD&#xff09; 3、总结…

【人工智能大语言模型技术发展研究报告 2024】

文末‍有福利&#xff01; 人工智能作为引领新一轮科技产业革命的战略性技术和新质生产力重要驱动力&#xff0c;正在引发经济、社会、文化等领域的变革和重塑&#xff0c;2023 年以来&#xff0c;以 ChatGPT、GPT-4 为代表的大模型技术的出台&#xff0c;因其强大的内容生成及…