树形结构的处理——组合模式(一)
树形结构在软件中随处可见,例如操作系统中的目录结构、应用软件中的菜单、办公系统中的公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题,组合模式通过一种巧妙的设计方案使得用户可以一致性地处理整个树形结构或者树形结构的一部分,也可以一致性地处理树形结构中的叶子节点(不包含子节点的节点)和容器节点(包含子节点的节点)。下面将学习这种用于处理树形结构的组合模式。
11.1 设计杀毒软件的框架结构
Sunny软件公司欲开发一个杀毒(AntiVirus)软件,该软件既可以对某个文件夹(Folder)杀毒,也可以对某个指定的文件(File)进行杀毒。该杀毒软件还可以根据各类文件的特点,为不同类型的文件提供不同的杀毒方式,例如图像文件(ImageFile)和文本文件(TextFile)的杀毒方式就有所差异。现需要提供该杀毒软件的整体框架设计方案。 |
在介绍Sunny公司开发人员提出的初始解决方案之前,我们先来分析一下操作系统中的文件目录结构,例如在Windows操作系统中,存在如图11-1所示目录结构:
图11-1 Windows目录结构
图11-1可以简化为如图11-2所示树形目录结构:
图11-2 树形目录结构示意图
我们可以看出,在图11-2中包含文件(灰色节点)和文件夹(白色节点)两类不同的元素,其中在文件夹中可以包含文件,还可以继续包含子文件夹,但是在文件中不能再包含子文件或者子文件夹。在此,我们可以称文件夹为容器(Container),而不同类型的各种文件是其成员,也称为叶子(Leaf),一个文件夹也可以作为另一个更大的文件夹的成员。如果我们现在要对某一个文件夹进行操作,如查找文件,那么需要对指定的文件夹进行遍历,如果存在子文件夹则打开其子文件夹继续遍历,如果是文件则判断之后返回查找结果。
Sunny软件公司的开发人员通过分析,决定使用面向对象的方式来实现对文件和文件夹的操作,定义了如下图像文件类ImageFile、文本文件类TextFile和文件夹类Folder:
//为了突出核心框架代码,我们对杀毒过程的实现进行了大量简化
import java.util.*; //图像文件类
class ImageFile { private String name; public ImageFile(String name) { this.name = name; } public void killVirus() { //简化代码,模拟杀毒 System.out.println("----对图像文件'" + name + "'进行杀毒"); }
} //文本文件类
class TextFile { private String name; public TextFile(String name) { this.name = name; } public void killVirus() { //简化代码,模拟杀毒 System.out.println("----对文本文件'" + name + "'进行杀毒"); }
} //文件夹类
class Folder { private String name; //定义集合folderList,用于存储Folder类型的成员 private ArrayList<Folder> folderList = new ArrayList<Folder>(); //定义集合imageList,用于存储ImageFile类型的成员 private ArrayList<ImageFile> imageList = new ArrayList<ImageFile>(); //定义集合textList,用于存储TextFile类型的成员 private ArrayList<TextFile> textList = new ArrayList<TextFile>(); public Folder(String name) { this.name = name; } //增加新的Folder类型的成员 public void addFolder(Folder f) { folderList.add(f); } //增加新的ImageFile类型的成员 public void addImageFile(ImageFile image) { imageList.add(image); } //增加新的TextFile类型的成员 public void addTextFile(TextFile text) { textList.add(text); } //需提供三个不同的方法removeFolder()、removeImageFile()和removeTextFile()来删除成员,代码省略 //需提供三个不同的方法getChildFolder(int i)、getChildImageFile(int i)和getChildTextFile(int i)来获取成员,代码省略 public void killVirus() { System.out.println("****对文件夹'" + name + "'进行杀毒"); //模拟杀毒 //如果是Folder类型的成员,递归调用Folder的killVirus()方法 for(Object obj : folderList) { ((Folder)obj).killVirus(); } //如果是ImageFile类型的成员,调用ImageFile的killVirus()方法 for(Object obj : imageList) { ((ImageFile)obj).killVirus(); } //如果是TextFile类型的成员,调用TextFile的killVirus()方法 for(Object obj : textList) { ((TextFile)obj).killVirus(); } }
}
编写如下客户端测试代码进行测试:
class Client { public static void main(String args[]) { Folder folder1,folder2,folder3; folder1 = new Folder("Sunny的资料"); folder2 = new Folder("图像文件"); folder3 = new Folder("文本文件"); ImageFile image1,image2; image1 = new ImageFile("小龙女.jpg"); image2 = new ImageFile("张无忌.gif"); TextFile text1,text2; text1 = new TextFile("九阴真经.txt"); text2 = new TextFile("葵花宝典.doc"); folder2.addImageFile(image1); folder2.addImageFile(image2); folder3.addTextFile(text1); folder3.addTextFile(text2); folder1.addFolder(folder2); folder1.addFolder(folder3); folder1.killVirus(); }
}
编译并运行程序,输出结果如下:
****对文件夹'Sunny的资料'进行杀毒 ****对文件夹'图像文件'进行杀毒 ----对图像文件'小龙女.jpg'进行杀毒 ----对图像文件'张无忌.gif'进行杀毒 ****对文件夹'文本文件'进行杀毒 ----对文本文件'九阴真经.txt'进行杀毒 ----对文本文件'葵花宝典.doc'进行杀毒 |
Sunny公司开发人员“成功”实现了杀毒软件的框架设计,但通过仔细分析,发现该设计方案存在如下问题:
(1) 文件夹类Folder的设计和实现都非常复杂,需要定义多个集合存储不同类型的成员,而且需要针对不同的成员提供增加、删除和获取等管理和访问成员的方法,存在大量的冗余代码,系统维护较为困难;
(2) 由于系统没有提供抽象层,客户端代码必须有区别地对待充当容器的文件夹Folder和充当叶子的ImageFile和TextFile,无法统一对它们进行处理;
(3) 系统的灵活性和可扩展性差,如果需要增加新的类型的叶子和容器都需要对原有代码进行修改,例如如果需要在系统中增加一种新类型的视频文件VideoFile,则必须修改Folder类的源代码,否则无法在文件夹中添加视频文件。
面对以上问题,Sunny软件公司的开发人员该如何来解决?这就需要用到本章将要介绍的组合模式,组合模式为处理树形结构提供了一种较为完美的解决方案,它描述了如何将容器和叶子进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器和叶子。
【作者:刘伟 http://blog.csdn.net/lovelion】
树形结构的处理——组合模式(一)相关推荐
- 树形结构的处理——组合模式(五)
11.5 公司组织结构 在学习和使用组合模式时,Sunny软件公司开发人员发现树形结构其实随处可见,例如Sunny公司的组织结构就是"一棵标准的树",如图11-8所示: 图11-8 ...
- 树形结构的处理——组合模式(二)
11.2 组合模式概述 对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子对象)并调用执行,牵一而动百,其中使用了 ...
- 树形结构的处理——组合模式(三)
11.3 完整解决方案 为了让系统具有更好的灵活性和可扩展性,客户端可以一致地对待文件和文件夹,Sunny公司开发人员使用组合模式来进行杀毒软件的框架设计,其基本结构如图11-5所示: 图11-5 ...
- 树形结构的处理——组合模式(四)
11.4 透明组合模式与安全组合模式 通过引入组合模式,Sunny公司设计的杀毒软件具有良好的可扩展性,在增加新的文件类型时,无须修改现有类库代码,只需增加一个新的文件类作为AbstractFile ...
- 组合模式 -- 树形结构处理
树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题,组合模式通过一种巧妙的设计方案使得 ...
- java设计模式之组合模式(树形层级)
java设计模式之组合模式 学习难度:★★★☆☆,使用频率:★★★★☆] 树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式来 ...
- 【学习设计模式11】树形处理——组合模式
上篇: [学习设计模式10]分离抽象与实现--桥接模式_Aiky哇的博客-CSDN博客上篇:[学习设计模式9]兼容扩展坞-适配器模式_Aiky哇的博客-CSDN博客上篇:[学习设计模式8]组装流水线- ...
- 【设计模式】组合模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
文章目录 一.组合模式简介 二.组合模式适用场景 三.组合模式优缺点 四.组合模式和访问者模式 五.组合模式代码示例 1.书籍和目录的抽象父类 2.书籍类 3.目录类 4.测试类 一.组合模式简介 组 ...
- 1、【设计模式】组合模式
java设计模式之组合模式 [学习难度:★★★☆☆,使用频率:★★★★☆] 树形结构在软件中随处可见,例如操作系统中的目录结构.应用软件中的菜单.办公系统中的公司组织结构等等,如何运用面向对象的方式 ...
- 组合模式的安全模式与透明模式
转载自 树形结构的处理--组合模式(四) 1 透明组合模式与安全组合模式 通过引入组合模式,Sunny公司设计的杀毒软件具有良好的可扩展性,在增加新的文件类型时,无须修改现有类库代码,只需增加一个新的 ...
最新文章
- 在.NET2.0中解析Json和Xml
- 你所需要的java网络编程大总结
- JS的parseFloat
- Linux使用systemctl设置程序开机自启动
- python如何控制浏览器_控制使用Python浏览器?
- VUE config/index.js文件配置
- App Store中国区下架近5万款未提供版号的游戏;微软源代码遭黑客访问;Rust 1.49.0发布
- C++程序中可以没有using namespace std;这一句吗
- linux shell 脚本实现:根据文件内容中的每行分隔符放入数组,根据规则打印日志并重新创建目录 备份文件
- 2017百度之星程序设计大赛 - 资格赛 1003
- 小程序开发教程 微信小程序视频教程
- 2001年广西壮族自治区植被类型分布数据
- 经典小游戏开发思路和算法之拼图(1)
- linux美元符号切换为井号,struts2 (# % $)井号,百分号,美元符号的含义和使用方法举例...
- Win10下运行复活之秦殇前传
- 我的世界java版如何装mod_我的世界MOD安装详解教程 全方位介绍MOD
- 解决 oracle 错误ORA-01033
- 国家统计局2020年6月30日最新省/市/县三级json数据(不包含港澳台)
- mysql中获取时间的年月日_详解mysql 获取当前日期及格式化
- Android Studio从入门到精通的免费视频教程
热门文章
- ajax 循环出数据库,each遍历 ajax 如何倒序插入数据库
- 【Java编程】写一个将华氏温度转换成摄氏温度的程序,转换的公式是:°F = (9/5)*°C + 32 其中C表示摄氏温度,F表示华氏温度。
- C语言中将二进制转换成十进制
- 服务器机房日常维护记录表,机房设备维护记录表
- JavaScript原理(一)
- CPC是什么意思和CPM、CPV有什么不同?
- 玩转软件|通过汉化WINRAR,手把手教你如何汉化软件
- 更好的为学计算机帮助英语,北京教委公布本科跨省转学名单,两学霸为学计算机转出北大...
- linux中括号的用法,【shell】Linux shell中括号的用法
- winserver2008 安装elasticsearch