二話不說,砸門先來看一個複製文件的例子
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接口操縱組合部件的對象。