将对象组合成树形结构以表示“整体—部分”的层次结构。组合(Composite)模式使单个对象和组合对象的使用具有一致性。
把组合模式看成是树形结构的话,它的主要角色有:
1) 树干角色(Component)–抽象组件:该角色是一个抽象类,它定义了一些操作增删树叶(Leaf)的操作。
2) 树枝角色(Composite)–容器组件:树枝上有很多树干,树枝也是树干的一种。
3) 树叶角色(Leaf)–叶子组件:树干上的树叶,也就是Component中的具体操作对象。
现实中很多东西都是树形结构的,比如操作系统的C D E F盘中的文件都是树形的,一些公司的组织架构也是树形的。
举例如下:(组件=角色)
/**
* 抽象组件
*
*/
public interface Component {
void operation();
}
//叶子组件
interface Leaf extends Component {
}
//容器组件
interface Composite extends Component {
void add(Component c);
void remove(Component c);
Component getChild(int index);
}
一个比较典型的应用就是杀毒软件查杀文件或者查杀文件夹,举例如下:
import java.util.ArrayList;
import java.util.List;
//抽象组件
public interface AbstractFile {
void killVirus(); //杀毒
}
//叶子组件 ImageFile
class ImageFile implements AbstractFile {
private String name;
public ImageFile(String name) {
super();
this.name = name;
}
@Override
public void killVirus() {
System.out.println("对图像文件:"+name+",进行查杀!");
}
}
//叶子组件 TextFile
class TextFile implements AbstractFile {
private String name;
public TextFile(String name) {
super();
this.name = name;
}
@Override
public void killVirus() {
System.out.println("对文本文件:"+name+",进行查杀!");
}
}
//叶子组件 VideoFile
class VideoFile implements AbstractFile {
private String name;
public VideoFile(String name) {
super();
this.name = name;
}
@Override
public void killVirus() {
System.out.println("对视频文件:"+name+",进行查杀!");
}
}
//容器组件 Folder
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);
}
@Override
public void killVirus() {
System.out.println("对文件夹:"+name+",进行查杀");
for (AbstractFile file : list) {//内部递归
file.killVirus();
}
}
}
测试:
public class Client {
public static void main(String[] args) {
AbstractFile f2,f3,f4,f5;
Folder f1 = new Folder("我的收藏");//文件夹
f2 = new ImageFile("某人的头像.jpg");
f3 = new TextFile("HelloWorld.txt");
f1.add(f2);
f1.add(f3);
Folder f11 = new Folder("电影");//文件夹
f4 = new VideoFile("笑傲江湖.avi");
f5 = new VideoFile("神雕侠侣.avi");
f11.add(f4);
f11.add(f5);
f1.add(f11);
f2.killVirus();//单独查杀某个文件
f1.killVirus();//查杀文件夹
}
}
运行结果:
对图像文件:某人的头像.jpg,进行查杀!
对文件夹:我的收藏,进行查杀
对图像文件:某人的头像.jpg,进行查杀!
对文本文件:HelloWorld.txt,进行查杀!
对文件夹:电影,进行查杀
对视频文件:笑傲江湖.avi,进行查杀!
对视频文件:神雕侠侣.avi,进行查杀!