1.定义
将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
2.使用场景
表示对象的整体-部分层次结构时
从一个整体能够独立出部分模块或功能的场景
3.简单实现
以操作系统的文件系统为例。
//抽象文件和文件夹 abstract class Dir{ //存储文件夹下的所有文件 List<Dir> list = new ArrayList<>(); private String name;//文件或者文件夹名称 public Dir(String name){ this.name = name; } //添加文件或文件夹 abstract void addDir(Dir dir); //移除文件或文件夹 abstract void removeDir(Dir dir); //清空文件夹下所有元素 abstract void clear(); //输出文件夹结构目录 abstract void print(); //获取文件夹下所有的文件夹或文件 abstract List<Dir> getFiles(); //获取文件或文件夹名称 public String getName() { return name; } } //文件夹 class Folder extends Dir{ public Folder(String name) { super(name); } @Override void addDir(Dir dir) { list.add(dir); } @Override void removeDir(Dir dir) { list.remove(dir); } @Override void clear() { list.clear(); } @Override void print() { System.out.print(getName() + " ( "); Iterator iterator = list.iterator(); while (iterator.hasNext()){ Dir dir = (Dir) iterator.next(); dir.print(); if (iterator.hasNext()){ System.out.print(" , "); } } System.out.print(" ) "); } @Override List<Dir> getFiles() { return list; } } //文件 class File extends Dir{ public File(String name) { super(name); } @Override void addDir(Dir dir) { throw new UnsupportedOperationException("文件对象不支持该操作"); } @Override void removeDir(Dir dir) { throw new UnsupportedOperationException("文件对象不支持该操作"); } @Override void clear() { throw new UnsupportedOperationException("文件对象不支持该操作"); } @Override void print() { System.out.print(getName()); } @Override List<Dir> getFiles() { throw new UnsupportedOperationException("文件对象不支持该操作"); } } public class ComponentMode { public static void main(String[] args){ //构造一个目录对象表示"C"盘 Dir dirC = new Folder("C:"); //添加一个文件 dirC.addDir(new File("IamFile.exe")); //添加三个文件夹 Dir FolderA = new Folder("FolderA"); dirC.addDir(FolderA); Dir FolderB = new Folder("FolderB"); dirC.addDir(FolderB); Dir FolderC = new Folder("FolderC"); dirC.addDir(FolderC); //A目录下2个文件 FolderA.addDir(new File("aaa.txt")); FolderA.addDir(new File("aaa2.txt")); //C目录下一个文件 FolderC.addDir(new File("ccc.txt")); //输出目录结构 dirC.print(); } }
输出:
4.小结
优点:
组合模式可以清楚定义分层次的复杂对象,表示对象的全部或者部分层次,它让高层模块忽略了层次差异,方便对整个层次结构控制。
高层模块可以一致地使用一个组合结构或者其中单个对象,不必关系处理的是单个对象还是整个组合结构,简化了高层模块的代码。
在组合模式中增加新的枝干结构和叶子构件很方便,无需对现有类库进行任何修改。
对树形结构面向对象提供了一种灵活的解决方案,通过递归可以形成复杂的树形结构,但对树形结构的控制确非常简单。
缺点:
在新增构件时不好对枝干中的构件类型进行限制,必须进行类的检查来实现,现实过程比较复杂。