1、什么是组合模式
组合模式是一种方案,能够让用户可以一致性地处理整个树形结构(容器构件)或树形结构的一部分(叶子构件)。虽然两部分表现出的功能不一样,整体使用上无太大差别。
2、组合模式应用场景
1:在具有整体和部分的层次结构中,希望通过一种方式忽略整体和部分的差异,客户端可以一致性对待处理。
2:处理的是一个树形结构。
3:系统中可以分离出叶子对象和容器对象,而且他们的类型不固定,需要增加一些新的类型。
遍历文件夹进行文件类型、数量、大小的统计。文件夹内可能包含子文件夹(容器文件),也可能只有具体格式的文件,即叶子文件。
3、组合模式示例
首先区分一下透明式组合模式和安全型组合模式
透明式组合模式:
抽象构件中声明了所有用于管理成员对象的方法,确保所有构件类都有相同的接口。在客户端看来叶子构件和容器构件所提供的方法一致的。具体可参考示例

安全型组合模式:
抽象构件中声明构件操作的方法,叶子构件继承方法重写实现具体的操作,而在组合类中声明并实现用于管理成员对象(构件)的方法,这样叶子构件根本看不到管理成员对象的方法,避免在使用中出现异常操作。

透明式组合示例:
AbstractFile --抽象构件类
/** * @Description 抽象构件 * @CreateDate 2019-09-15-21:28 */public abstract class AbstractFile { public abstract void add(AbstractFile file); public abstract void remove(AbstractFile file); public abstract AbstractFile getChild(int i); public abstract void killVirus();}
import java.util.ArrayList;
/**
* @Description 文件容器类:容器构件
* @CreateDate 2019-09-15-21:42
*/
public class Folder extends AbstractFile {
private String name;
public Folder(String name){
this.name = name;
}
private ArrayList<AbstractFile> fileList = new ArrayList<>();
@Override
public void add(AbstractFile file) {
fileList.add(file);
}
@Override
public void remove(AbstractFile file) {
fileList.remove(file);
}
@Override
public AbstractFile getChild(int i) {
return (AbstractFile)fileList.get(i);
}
@Override
public void killVirus() {
System.out.println("****对文件夹'" + name + "'进行杀毒");
for (Object obj : fileList) {
((AbstractFile)obj).killVirus();
}
}
}
/**
* @Description 文本文件类:叶子构件
* @CreateDate 2019-09-15-21:35
*/
public class TextFile extends AbstractFile {
private String name;
public TextFile(String name){
this.name = name;
}
@Override
public void add(AbstractFile file) {
System.out.println("对不起,不支持该方法!");
}
@Override
public void remove(AbstractFile file) {
System.out.println("对不起,不支持该方法!");
}
@Override
public AbstractFile getChild(int i) {
System.out.println("对不起,不支持该方法!");
return null;
}
@Override
public void killVirus() {
//模拟杀毒
System.out.println("----对文本文件'" + name + "'进行杀毒");
}
}
客户端测试代码
/**
* @Description TODO
* @CreateDate 2019-09-15-21:51
*/
public class CompositeClient {
public static void main(String[] args) {
AbstractFile file1,file2,file3,file4,file5,folder1,folder2,folder3,folder4;
folder1 = new Folder("Sunny的资料");
folder3 = new Folder("文本文件");
file3 = new TextFile("九阴真经.txt");
file4 = new TextFile("葵花宝典.doc");
folder3.add(file3);
folder3.add(file4);
folder1.add(folder3);
folder1.killVirus();
}
}
4、组合模式优缺点
优点:
1:客户端一致的使用组合结构或单个对象,不需要关心处理的对象类别
2:增加新的容器构件和叶子构件都很方便,无需对现有类库进行任务修改,符合“开闭原则”
3:可以很简单的处理树形结构。
缺点:
1:添加构件时很难对容器中的构件类进行限制。
本文参考http://gof.quanke.name/