组合模式
系统中通常有很多比较复杂的数据结构,如常见的目录、导航、菜单等结构,如果为每一个目录和标签写单独的方法,那么会非常麻烦,假设我们要删除一个文件夹,如果要人工的打开文件夹,判断里面的每个内容是文件夹或者文件,如果文件夹继续打开判断,如果是文件就删除。。。而实际中,我们只要右键-删除-确定就可以了,这个就是由组合模式来实现的。
组合模式通过树形结构,将复杂的对象表示成容器和叶子,它模糊了简单对象和复杂对象的概念,使得系统可以像操作简单对象一样操作复杂对象。
定义
组合多个对象形成树形结构以表示具有部分-整体关系的层次结构,组合模式让客户端可以统一对待单个对象和组合对象。
构成
- Component 抽象构件。它可以是接口或者抽象类,该角色提供了所有子类添加、删除、获取、执行的方法。
- Leaf 叶子构件。它在组合模式中表示叶子节点,它没有子节点,不能添加、删除获取子节点,只能执行本身方法。
- Composite 容器构件。它在组合模式中表示容器构件,包含子节点,有添加、删除、获取子节点功能,执行业务方法即便利子节点,执行子节点的业务方法。
实例
通过代码完成文件夹删除功能
package composite;
public interface File {
public void add(File file);
public void remove(File file);
public File get(Integer i);
public void delete();
}
package composite;
import java.util.ArrayList;
import java.util.List;
public class Folder implements File {
private List<File> files = new ArrayList<>();
@Override
public void add(File file) {
this.files.add(file);
}
@Override
public void remove(File file) {
this.files.remove(file);
}
@Override
public File get(Integer i) {
return this.files.get(i);
}
@Override
public void delete() {
if (!this.files.isEmpty()) {
for (File file : files) {
file.delete();
}
}
System.out.println("删除文件夹");
}
}
package composite;
public class ImgFile implements File {
@Override
public void add(File file) {
throw new RuntimeException("没有添加功能");
}
@Override
public void remove(File file) {
throw new RuntimeException("没有移除功能");
}
@Override
public File get(Integer i) {
throw new RuntimeException("没有获取功能");
}
@Override
public void delete() {
System.out.println("删除IMG文件");
}
}
package composite;
public class TxtFile implements File {
@Override
public void add(File file) {
throw new RuntimeException("没有添加功能");
}
@Override
public void remove(File file) {
throw new RuntimeException("没有移除功能");
}
@Override
public File get(Integer i) {
throw new RuntimeException("没有获取功能");
}
@Override
public void delete() {
System.out.println("删除TXT文件");
}
}
package composite;
public class Test {
public static void main(String[] args) {
File file = new Folder();
file.add(new ImgFile());
file.add(new TxtFile());
file.delete();
}
}
透明组合模式和安全组合模式
- 透明组合模式。抽象构建中声明了所有的方法,它的子类需要去实现这些方法,但是这样会导致叶子节点去实现自己不需要的方法,没有意义。
- 安全组合模式。抽象构建中只声明了业务方法,子节点管理方法只在容器构件中单独声明,这样叶子节点不会有多余的方法,但是这样不能进行面向抽象构建编程。
优点
- 客户端可以一致的对待容器中的对象,不用关心是单个对象还是容器,减少了代码的复杂度。
- 增加新的容器对象和叶子对象都非常方便,符合开闭原则。
- 通过递归组合提供了解决复杂树形结构的实现方案。
适用场景
- 树形结构
- 业务执行的时候希望忽略部分与整体的差异,客户端可以一致的对待所有对象。