组合模式(Composite pattern)
概念
把部分和整体的关系用树形结构来表示,从而使客户端可以使用同一的方式处理部分对象和整体对象
应用场景
1:操作系统的资源管理器
2:GUI的容器层次图
3:XML文件解析
4:OA系统中,组织结构的处理
5:Junit单元测试框架,底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器)、Test接口(抽象)
核心
1:抽象(Component)构件角色,定义了叶子和容器构件的共同点
2:叶子(Leaf)构件角色,无子节点
3:容器(Composite)构件角色,有容器特征,可以包含子节点
/*
* 抽象组件
*/
public interface Component {
public abstract void operation();
}
/*
* 叶子组件
*/
interface Leaf extends Component{
}
/*
* 容器组件
*/
interface Composite extends Component{
//添加组件
public abstract void add(Component c);
//删除组件
public abstract void remove(Component c);
//返回组件
public abstract Component getChild(int index);
}
UML图
案例(软件杀毒)
抽象构件(Component)
/*
* 抽象构件
*/
public interface AbstractFile {
public abstract void killVirus();//杀毒功能
}
叶子节点(Leaf)
/*
* 叶子节点(Leaf),显然以下节点中不存在子节点
*/
//图像杀毒
class ImageFile implements AbstractFile{
private String name;
public ImageFile(String name) {
super();
this.name = name;
}
public void killVirus() {
System.out.println("对" + name + "图像进行杀毒!");
}
}
//文本杀毒
class TextFile implements AbstractFile{
private String name;
public TextFile(String name) {
super();
this.name = name;
}
public void killVirus() {
System.out.println("对" + name + "文本进行杀毒!");
}
}
//视频杀毒
class VideoFile implements AbstractFile{
private String name;
public VideoFile(String name) {
super();
this.name = name;
}
public void killVirus() {
System.out.println("对" + name + "视频进行杀毒!");
}
}
容器构件(
Composite)
/*
* 容器构件(Composite)
*/
class Folder implements AbstractFile{
private String name;
//定义容器,用来存放容器构造下的子节点
private List<AbstractFile> list = new ArrayList<AbstractFile>();
public Folder(String name) {
super();
this.name = name;
}
//添加容器
public void add(AbstractFile file){
list.add(file);
}
//删除容器
public void remove(AbstractFile file){
list.remove(file);
}
//获取容器
public AbstractFile getChild(int index){
return list.get(index);
}
//杀毒,采用了一个递归调用(如果是文件,直接查杀,如果是文件夹,递归)
public void killVirus() {
System.out.println(name + "文件夹" + "-----" + "开始查杀!");
for (AbstractFile abstractFile : list) {
abstractFile.killVirus();
}
}
}
客户端测试
public class Client {
public static void main(String[] args) {
Folder f1 = new Folder("我的收藏");
AbstractFile image = new ImageFile("杰拉德.jpg");
AbstractFile text = new TextFile("亨德森.txt");
AbstractFile video = new VideoFile("克洛普.video");
f1.add(image);
f1.add(text);
f1.add(video);
// f1.killVirus();
//创建子文件夹进行测试
Folder f2 = new Folder("利物浦专辑");
AbstractFile video1 = new VideoFile("苏亚雷斯.video");
AbstractFile video2 = new VideoFile("阿格尔.video");
AbstractFile image1 = new ImageFile("斯图里奇.txt");
f2.add(video1);
f2.add(video2);
f2.add(image1);
f1.add(f2);
f1.killVirus();
}
}
console:
我的收藏文件夹-----开始查杀!
对杰拉德.jpg图像进行杀毒!
对亨德森.txt文本进行杀毒!
对克洛普.video视频进行杀毒!
利物浦专辑文件夹-----开始查杀!
对苏亚雷斯.video视频进行杀毒!
对阿格尔.video视频进行杀毒!
对斯图里奇.txt图像进行杀毒!