组合模式
什么是组合模式
组合模式(Composite Pattern)允许你将对象组合成树形结构以表示“部分-整体”的层次结构,使得客户端以统一的方式处理单个对象和对象的组合。组合模式让你可以将对象组合成树形结构,并且能像单独对象一样使用它们。
组合模式使用场景
把部分和整体的关系用树形结构来表示,从而是客户端可以使用统一的方式处理部分对象和整体对象。
组合模式核心
抽象构件(Component)角色:定义了叶子和容器构件的共同特点
叶子(Leaf)构件角色:无子节点
容器(Composite)构件角色:有容器特征,可以包含子节点
组合模式工作流程分析
- 组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,是的用户在使用是可以一致性的对待容器和叶子
- 当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也抱恨这个方法的成员,并调用执行,其中使用了递归调用的机制对整个结构进行处理。
代码实现结构
Component.java
// 抽象构件
public interface Component {
// 相同行为操作
void operation();
}
Leaf.java
// 叶子
public class Leaf implements Component {
@Override
public void operation() {
System.out.println("叶子单独操作");
}
}
Composite.java
import java.util.ArrayList;
import java.util.List;
// 容器节点
public class Composite implements Component{
// 作为容器存储子节点信息
private List<Component> components = new ArrayList<>();
public Composite(List<Component> components) {
this.components = components;
}
public List<Component> getComponents() {
return components;
}
public void setComponents(List<Component> components) {
this.components = components;
}
@Override
public void operation() {
System.out.println("容器构件操作");
for (Component component : components) {
// 递归执行叶子节点操作
component.operation();
}
}
}
案例
模拟杀毒软件的架构设计
UML
实现代码
AbstractFile.java
// 抽象组件
public interface AbstractFile {
// 杀毒功能
void killVirus();
}
ImagesFile.java
// 图片类型文件
public class ImagesFile implements AbstractFile{
private String name;
public ImagesFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.printf("图片类型文件-%s-进行扫毒%n",this.name);
}
}
TxtFile.java
// 文本类型文件
public class TxtFile implements AbstractFile{
private String name;
public TxtFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.printf("文本类型文件-%s-进行扫毒%n",this.name);
}
}
VideoFile.java
// 视频类型文件
public class VideoFile implements AbstractFile{
private String name;
public VideoFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.printf("视频类型文件-%s-进行扫毒%n",this.name);
}
}
Floder.java
import java.util.ArrayList;
import java.util.List;
// 容器构件:目录
public class Floder implements AbstractFile{
private String name;
// 子节点
private List<AbstractFile> lists = new ArrayList<AbstractFile>();
public Floder(String name, List<AbstractFile> lists) {
this.name = name;
this.lists = lists;
}
@Override
public void killVirus() {
System.out.printf("扫描当前目录-%s%n",this.name);
for(AbstractFile abstractFile : lists){
abstractFile.killVirus();
}
}
}
TestClient.java
import java.util.ArrayList;
import java.util.List;
public class TestClient {
public static void main(String[] args) {
AbstractFile file1 = new TxtFile("花无缺.TXT");
AbstractFile file2 = new ImagesFile("花无缺.png");
AbstractFile file3 = new ImagesFile("花无缺.avi");
List<AbstractFile> list = new ArrayList<AbstractFile>();
list.add(file1);
list.add(file2);
list.add(file3);
Floder floder = new Floder("huawuque",list);
AbstractFile file4 = new TxtFile("小鱼儿.TXT");
AbstractFile file5 = new ImagesFile("小鱼儿.png");
AbstractFile file6 = new ImagesFile("小鱼儿.avi");
List<AbstractFile> list1 = new ArrayList<AbstractFile>();
list1.add(file4);
list1.add(file5);
list1.add(file6);
Floder floder2 = new Floder("xuaiyuer",list1);
List<AbstractFile> list3 = new ArrayList<AbstractFile>();
list3.add(floder);
list3.add(floder2);
Floder floder3 = new Floder("绝代双骄",list3);
floder3.killVirus();
}
}
执行结果