当前位置: 首页 > news >正文

设计模式-结构型模式-组合模式

1.组合模式的定义

        将对象组合成树形结构以表示整个部分的层次结构,组合模式可以让用户统一对待单个对象和对象的组合;其更像是一种数据结构和算法的抽象,其中数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现;

1.1 组合模式优缺点

优点

  • 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。

  • 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。

  • 在组合模式中增加新的树枝节点和叶子节点都很方便,无须对现有类库进行任何修改,符合“开闭原则”。

  • 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。

缺点

  • 使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也 比较局限,它并不是一种很常用的设计模式。

1.2 组合模式的使用场景

  • 处理一个树形结构,比如,公司人员组织架构、订单信息等;

  • 跨越多个层次结构聚合数据,比如,统计文件夹下文件总数;

  • 统一处理一个结构中的多个对象,比如,遍历文件夹下所有 XML 类型文件内容。

2.组合模式原理

  • 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性;
  • 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构;
  • 叶子节点(Leaf):叶子节点对象,没有子节点,是系统层次遍历的最小单位;

3.组合模式的实现

【实例】

        列出某一目录下所有的文件和文件夹

【代码】

        Entry类,抽象类,用来定义File类与Directory类的共性内容

public abstract class Entry {public abstract String getName(); //获取文件名public abstract int getSize(); //获取文件大小//添加文件夹或文件public abstract Entry add(Entry entry);//显示指定目录下的所有信息public abstract void printList(String prefix);@Overridepublic String toString() {return getName() + "(" +getSize() + ")";}
}

         File类,叶子节点,表示文件

public class File extends Entry {private String name; //文件名private int size; //文件大小public File(String name, int size) {this.name = name;this.size = size;}@Overridepublic String getName() {return name;}@Overridepublic int getSize() {return size;}@Overridepublic Entry add(Entry entry) {return null;}@Overridepublic void printList(String prefix) {System.out.println(prefix + "/" + this);}
}

        Directory类,树枝节点,表示文件

public class Directory extends Entry{//文件的名字private String name;//文件夹与文件的集合private ArrayList<Entry> directory = new ArrayList();//构造函数public Directory(String name) {this.name = name;}//获取文件名称@Overridepublic String getName() {return this.name;}/*** 获取文件大小*      1.如果entry对象是File类型,则调用getSize方法获取文件大小*      2.如果entry对象是Directory类型,会继续调用子文件夹的getSize方法,形成递归调用.*/@Overridepublic int getSize() {int size = 0;//遍历或者去文件大小for (Entry entry : directory) {size += entry.getSize();}return size;}@Overridepublic Entry add(Entry entry) {directory.add(entry);return this;}//显示目录@Overridepublic void printList(String prefix) {System.out.println("/" + this);for (Entry entry : directory) {entry.printList("/" + name);}}
}

        客户端

//根节点
Directory rootDir = new Directory("root");//树枝节点
Directory binDir = new Directory("bin");
//向bin目录中添加叶子节点
binDir.add(new File("vi",10000));
binDir.add(new File("test",20000));Directory tmpDir = new Directory("tmp");Directory usrDir = new Directory("usr");
Directory mysqlDir = new Directory("mysql");
mysqlDir.add(new File("my.cnf",30));
mysqlDir.add(new File("test.db",25000));
usrDir.add(mysqlDir);rootDir.add(binDir);
rootDir.add(tmpDir);
rootDir.add(mysqlDir);rootDir.printList("");

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 学习WebGl基础知识(二)
  • Docker原理及实例
  • 使用docker部署project-exam-system(项目)
  • QT connect的使用
  • SLM2110CG 1.0A/1.6A600V完美代替IR2110 精准驱动,可靠之芯 高压、高速的功率MOSFET和IGBT驱动器
  • 【深度解读】知识库的作用
  • NVIDIA GeForce RTX标志升级 加入AI的力量
  • 9、Django Admin优化查询
  • MacOS下WKWebView设置背景透明问题
  • 行业内幕曝光!全域运营公司究竟哪家好?
  • 【mac】MAC命令快速模糊查找文件
  • MySQL的事务认识
  • 国产游戏技术:迈向全球引领者的征途
  • 构建高效搜索系统 - Faiss向量数据库的快速入门
  • windows C++ 并行编程-并发的异常处理(三)
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • Angular Elements 及其运作原理
  • ES6 学习笔记(一)let,const和解构赋值
  • HTTP那些事
  • Netty 4.1 源代码学习:线程模型
  • SpringBoot几种定时任务的实现方式
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 初识MongoDB分片
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 免费小说阅读小程序
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 物联网链路协议
  • 写代码的正确姿势
  • 你对linux中grep命令知道多少?
  • raise 与 raise ... from 的区别
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​香农与信息论三大定律
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (ZT) 理解系统底层的概念是多么重要(by趋势科技邹飞)
  • (第一天)包装对象、作用域、创建对象
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (强烈推荐)移动端音视频从零到上手(上)
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (四)进入MySQL 【事务】
  • (四)模仿学习-完成后台管理页面查询
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .NET DataGridView数据绑定说明
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .Net FrameWork总结
  • .net MySql
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .net和jar包windows服务部署
  • .NET牛人应该知道些什么(2):中级.NET开发人员