二话不说,砸门先来看一个复制文件的例子
package com.zq.designpattern.composite;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zhengshouzi on 2015/10/28.
*/
public class CompositePattern {
public static void main(String[] args) {
//创建文件夹
Component root = new Folder("D:\\");
Component myPicture = new Folder("我的照片");
Component myDocument = new Folder("我的文档");
Component myVideo = new Folder("我的视频");
Component mySoftware = new Folder("我的软件");
Component studyVideo = new Folder("学习视频");
Component entertainmentVideo = new Folder("娱乐视频");
Component adultVideo = new Folder("adult视频");
//创建文件
Component androidVideo1 = new File("android1.avi");
Component androidVideo2 = new File("android2.avi");
Component androidVideo3 = new File("android3.avi");
Component androidVideo4 = new File("android4.avi");
Component phpvideo = new File("php.avi");
Component javavideo = new File("java.avi");
//把文件夹和文件添加到相应的位置
root.add(myDocument);
root.add(myPicture);
root.add(myVideo);
root.add(mySoftware);
myVideo.add(studyVideo);
myVideo.add(entertainmentVideo);
myVideo.add(adultVideo);
studyVideo.add(androidVideo1);
studyVideo.add(androidVideo2);
studyVideo.add(androidVideo3);
studyVideo.add(androidVideo4);
studyVideo.add(phpvideo);
studyVideo.add(javavideo);
root.delete(myDocument);
root.updateName("F:\\");
//拷贝文件夹
root.copy();
}
}
//文件和文件夹共有的操作,接口
interface Component{
void add(Component component);
void delete(Component component);
void updateName(String name);
void copy();
}
//文件夹类
class Folder implements Component{
//保存文件夹里面的东西
private List<Component> list ;
private String folderName;
public List<Component> getList() {
return list;
}
public void setList(List<Component> list) {
this.list = list;
}
public String getFolderName() {
return folderName;
}
public void setFolderName(String folderName) {
this.folderName = folderName;
}
public Folder(String folderName){
setFolderName(folderName);
setList(new ArrayList<Component>());
}
@Override
public void add(Component component) {
list.add(component);
}
@Override
public void delete(Component component) {
list.remove(component);
}
@Override
public void updateName(String name) {
setFolderName(name);
}
//当拷贝文件夹的时候,连带文件夹里面的所有内容一起拷贝,当然这个工作,交给各自的组合对象完成就行了
@Override
public void copy() {
System.out.println("复制文件夹:" +getFolderName());
for (Component component :getList()){
component.copy();
}
}
}
//文件类
class File implements Component{
private String fileName;
public File(String fileName) {
this.fileName = fileName;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
@Override
public void add(Component component) {
}
@Override
public void delete(Component component) {
}
@Override
public void updateName(String name) {
setFileName(name);
}
//文件拷贝工作
@Override
public void copy() {
System.out.println("复制文件: "+getFileName());
}
}
看懂了代码要表达的意思了吗。。就是要拷贝一个文件夹。我们就只是简单的拷贝了一个文件夹,然后所有的拷贝工作都交给组合成此文件夹的所有子文件夹或者文件去完成。
文件系统是树形层次结构,并且文件和文件夹都可以复制。那么我们通过提供一个统一的操作的接口,将文件和文件夹复制操作的不一致给屏蔽起来。我们在复制文件夹的时候,操作系统实现了对文件夹内的所有文件和文件夹的复制,即实现了组合对象的整体复制,而不是一个空的文件夹。这便是组合模式的妙处。
下面我们给出具体的组合模式的定义:
将对象组合成树形结构以表示“部分-整体”的层次结构。“Composite使得用户对单个对象和组合对象的使用具有一致性。”
类型:结构型模式。
类图:
1、你想表示对象的部分-整体层次结构。
2、你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象(使用文件夹中的所有子文件夹和文件)。
参与者:
1、Component
为组合中的对象声明接口(文件夹和文件的共同特征)。
在适当的情况下,实现所有类共有接口的缺省行为。
声明一个接口用于访问和管理Component的子组件。
(可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
2、Leaf(文件)
在组合中表示叶节点对象,叶节点没有子节点。
在组合中定义节点对象的行为。
3、Composite(文件夹)
定义有子部件的那些部件的行为。
存储子部件。
在Component接口中实现与子部件有关的操作。
4、Client
通过Component接口操纵组合部件的对象。