目录
1.组合模式概述
1.1 定义
在组合模式中通过多个对象形成树形结构以表示整体-部分层次。组合模式使得用户对单个对象和组合对象的使用具有一致性。
1.2 作用
将对象组织到树型结构中,可以用来描述整体与部分的关系。
1.3 应用场景
当发现需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就一个考虑使用组合模式。
1.4 分类
1.4.1 透明组合模式
1.4.2 安全组合模式
2.类图
类图如下所示:
3.角色
Component 表示抽象构件,它可以是接口或抽象类,为叶子构件和容器构件对象声明接口。在该角色中可以包含
所有子类共有行为的声明和实现。
在抽象构件中还定义了访问及管理子构件的方法,如add子构件,remove子构件,get子构件等。
Leaf 表示叶子构件,在组合中表示叶子节点对象。叶子节点没有子节点,它实现抽象构件声明的基本行为。 Composite 表示同期构件,定义了包含子节点(可以是叶子节点或容器节点)的构件的行为,并储存子节点
(叶子节点或容器节点),实现了抽象构件中定义的操作叶子构件的行为。
4.案例
4.1 说明
这里以文件夹和文件为案例:文件种类包括文本文件TextFile,图片文件ImageFile,视频文件VideoFile
4.2 创建
1)创建抽象文件类
/** * 抽象文件类:抽象构件 * @author Administrator */ public abstract class AbstractFile { //添加文件 public abstract void add(AbstractFile elelemt); //删除文件 public abstract void remove(AbstractFile element); //显示文件 public abstract void display(); }
2)创建文件夹类
/** * 文件夹类:容器构件 * @author Administrator */ public class Folder extends AbstractFile{ private List<AbstractFile> fileList = new ArrayList<>(); private String fileName; public Folder(String fileName) { this.fileName = fileName; } @Override public void add(AbstractFile elelemt) { fileList.add(elelemt); } @Override public void remove(AbstractFile element) { fileList.remove(element); } @Override public void display() { System.out.println("文件夹 :"+fileName + ",包含如下资料:"); for (Object obj : fileList) { ((AbstractFile)obj).display(); } } }
3)创建图片文件类
/** * 图片文件类:叶子构件 * @author Administrator */ public class ImageFile extends AbstractFile{ //图片文件名称 private String fileName; public ImageFile(String fileName) { this.fileName = fileName; } @Override public void add(AbstractFile elelemt) { System.out.println("不支持该方法!"); } @Override public void remove(AbstractFile element) { System.out.println("不支持该方法!"); } @Override public void display() { System.out.println("浏览图片文件:" + fileName); } }
4)创建文本文件类
/** * 文本文件类:叶子构件 * @author Administrator */ public class TextFile extends AbstractFile{ //文本文件名称 private String fileName; public TextFile(String fileName) { this.fileName = fileName; } @Override public void add(AbstractFile elelemt) { System.out.println("不支持该方法!"); } @Override public void remove(AbstractFile element) { System.out.println("不支持该方法!"); } @Override public void display() { System.out.println("浏览文本文件:" + fileName); } }
5)创建视频文件类
/** * 视频文件类:叶子构件 * @author Administrator */ public class VideoFile extends AbstractFile{ //视频文件名称 private String fileName; public VideoFile(String fileName) { this.fileName = fileName; } @Override public void add(AbstractFile elelemt) { System.out.println("不支持该方法!"); } @Override public void remove(AbstractFile element) { System.out.println("不支持该方法!"); } @Override public void display() { System.out.println("浏览视频文件:" + fileName); } }
6)客户端测试类
/** * 客户端测试类 * @author Administrator */ public class Client { public static void main(String[] args) { //创建图片文件 AbstractFile imageFile1 = new ImageFile("小猫.jpg"); AbstractFile imageFile2 = new ImageFile("小狗.png"); //创建文本文件 AbstractFile textFile1 = new ImageFile("设计模式.txt"); AbstractFile textFile2 = new ImageFile("程序设计.doc"); //创建视频文件 AbstractFile videoFile= new VideoFile("动物世界.mp4"); //创建图片文件夹 AbstractFile imageFolder = new Folder("图片文件夹"); imageFolder.add(imageFile1); imageFolder.add(imageFile2); //创建文本文件夹 AbstractFile textFolder = new Folder("文本文件夹"); textFolder.add(textFile1); textFolder.add(textFile2); //创建个人文件夹 AbstractFile personFolder = new Folder("个人文件夹"); //将视频文件、图片文件夹和文本文件夹添加到个人文件夹中 personFolder.add(videoFile); personFolder.add(imageFolder); personFolder.add(textFolder); //打印显示 personFolder.display(); } }
7)运行结果
文件夹 :个人文件夹,包含如下资料: 浏览视频文件:动物世界.mp4 文件夹 :图片文件夹,包含如下资料: 浏览图片文件:小猫.jpg 浏览图片文件:小狗.png 文件夹 :文本文件夹,包含如下资料: 浏览图片文件:设计模式.txt 浏览图片文件:程序设计.doc
4.3 分析
本例使用了透明组合模式,在抽象构件类里面定义了所有方法,包括管理子构件和打印信息的方法,然后在叶子构件实现类里面对管理子构件方法进行了出错处理。在文件夹容器构件类中的display方法里面调用了其子叶子构件成员对象的display方法,从而实现了对整个树形结构的遍历。
5.优缺点
5.1 优点
1.组合模式可以清楚的定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新的构件比较容易。 2.组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。 5.2 缺点