文章目录
- 概念
- 结构
- 实例
- 总结
概念
组合模式:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。
当我们开发中遇到树形结构的业务时,可以考虑使用组合模式。(我也没有想明白为啥叫组合模式,为啥不叫树形模式)
结构
组合模式类图如下:
Component(抽象构件):它可以是接口或者抽象类,是叶子构件和容器构件的接口,为其提供方法的声明。定义了访问和管理组件的方法。
Leaf(叶子构件):叶子构件是最底层的类,它没有子节点。对于一些没有的方法可以排出异常或者提示错误等方式进行处理。
Composite(容器构件):容器构件的子节点既可以是容器构件也可以是叶子构件,它提供了一个集合用于存储子节点,在其实现的业务方法中进行递归调用其子节点的业务方法。
实例
某公司要做一个杀毒软件,这个软件既可以对某个文件夹进行杀毒,也可以对指定某个文件进行杀毒,还支持为不同类型的文件提供不同的杀毒方式。现在用组合模式来实现这个功能。设计类图如下:
代码展示:
AbstractFile类,抽象的文件类。
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();
}
TextFile 文件
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);
}
}
ImageFile 文件
public class ImageFile extends AbstractFile {
private String name;
public ImageFile(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);
}
}
Folder
public class Folder extends AbstractFile {
private List<AbstractFile> fileList = new ArrayList<AbstractFile>();
private String name;
public Folder(String name) {
this.name = name;
}
@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 fileList.get(i);
}
@Override
public void killVirus() {
System.out.println("对文件夹杀毒 " + name);
for (AbstractFile file : fileList) {
file.killVirus();
}
}
}
客户端使用
public class Client {
public static void main(String[] args) {
AbstractFile folder1, folder2, folder3, file1, file2, file3, file4;
folder1 = new Folder("Sunny的资料");
folder2 = new Folder("图像文件夹");
folder3 = new Folder("文本文件夹");
file1 = new ImageFile("小龙女.jpg");
file2 = new ImageFile("张无忌.gif");
file3 = new TextFile("九阴真经.txt");
file4 = new TextFile("葵花宝典.txt");
folder1.add(folder2);
folder1.add(folder3);
folder2.add(file1);
folder2.add(file2);
folder3.add(file3);
folder3.add(file4);
//对folder 1 树形文件夹进行消毒
folder1.killVirus();
}
}
打印结果如下:
总结
组合模式很适用于处理树形结构的业务场景,主要组件为容器组件和叶子组件,从容器组件开始遍历,一层一层的处理当前组件的业务场景。如果想要扩展新的组件,也无需修改代码,符合开闭原则。当树形结构或者具有整体和部分的层次结构时,希望忽略整体和部分的差异,被客户端一致的对待,可以考虑使用组合模式。