文章目录
- 概念
- 结构
- 实例
- 总结
概念
组合模式:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。
当我们开发中遇到树形结构的业务时,可以考虑使用组合模式。(我也没有想明白为啥叫组合模式,为啥不叫树形模式)
结构
组合模式类图如下:
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;}@Overridepublic void add(AbstractFile file) {System.out.println("不支持该方法");}@Overridepublic void remove(AbstractFile file) {System.out.println("不支持该方法");}@Overridepublic AbstractFile getChild(int i) {System.out.println("不支持该方法");return null;}@Overridepublic void killVirus() {System.out.println("对文本文件杀毒 " + name);}
}
ImageFile 文件
public class ImageFile extends AbstractFile {private String name;public ImageFile(String name) {this.name = name;}@Overridepublic void add(AbstractFile file) {System.out.println("不支持该方法");}@Overridepublic void remove(AbstractFile file) {System.out.println("不支持该方法");}@Overridepublic AbstractFile getChild(int i) {System.out.println("不支持该方法");return null;}@Overridepublic 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;}@Overridepublic void add(AbstractFile file) {fileList.add(file);}@Overridepublic void remove(AbstractFile file) {fileList.remove(file);}@Overridepublic AbstractFile getChild(int i) {return fileList.get(i);}@Overridepublic 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();}}
打印结果如下:
总结
组合模式很适用于处理树形结构的业务场景,主要组件为容器组件和叶子组件,从容器组件开始遍历,一层一层的处理当前组件的业务场景。如果想要扩展新的组件,也无需修改代码,符合开闭原则。当树形结构或者具有整体和部分的层次结构时,希望忽略整体和部分的差异,被客户端一致的对待,可以考虑使用组合模式。