源代碼:https://gitee.com/AgentXiao/CompositePattern
要點(diǎn):
1、組合模式和組合的區(qū)別
2、組合模式的實(shí)現(xiàn)
3、組合模式的應(yīng)用場景
一、組合模式和組合
組合是一種類的關(guān)系,在A類中定義一個B類,A擁有了B,叫組合。
組合模式是一種設(shè)計(jì)模式。
二、組合模式
把部分和整體的關(guān)系用樹形結(jié)構(gòu)來表示,從而使客戶端可以使用統(tǒng)一的方式處理部分對象和整體對象。
組合模式的核心
(1)抽象構(gòu)件(Component)角色: 定義了葉子和容器構(gòu)件的共同點(diǎn).
(2)葉子(Leaf)構(gòu)件角色:無子節(jié)點(diǎn)。
(3)容器(Composite)構(gòu)件角色: 有容器特征,可以包含子節(jié)點(diǎn)。

組合模式的核心
組合模式為處理樹形結(jié)構(gòu)提供了完美的解決方案,描述了如何將容器和葉子進(jìn)行遞歸組合,使得用戶在使用時可以一致性的對待容器和葉子。當(dāng)容器對象的指定方法被調(diào)用時,將遍歷整個樹形結(jié)構(gòu),尋找也包含這個方法的成員,并調(diào)用執(zhí)行。
三、使用組合模式,模擬殺毒軟件架構(gòu)設(shè)計(jì)
抽象組件:
/**
* @InterfaceName AbstractFile
* @Description 抽象文件(文件和文件夾)
* @Author xwd
* @Date 2018/10/24 22:41
*/
public interface AbstractFile {
void killVirus();
}
葉子組件:
/**
* @className ImageFile
* @Description 圖像文件
* @Author xwd
* @Date 2018/10/24 22:42
*/
public class ImageFile implements AbstractFile {
private String name;
public ImageFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.println("查殺圖像文件:"+this.name);
}
}
/**
* @ClassName VideoFile
* @Description 視頻文件
* @Author xwd
* @Date 2018/10/24 22:45
*/
public class VideoFile implements AbstractFile{
private String name;
public VideoFile(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.println("查殺視頻文件:"+this.name);
}
}
容器組件:
/**
* @ClassName Folder
* @Description 文件夾
* @Author xwd
* @Date 2018/10/24 22:47
*/
public class Folder implements AbstractFile{
private String name;
private List<AbstractFile> list = new ArrayList<>();
/**
* @MethodName add
* @Descrition 添加文件、文件夾到文件夾
* @Param [file]
* @return void
*/
public void add(AbstractFile file){
list.add(file);
}
/**
* @MethodName remove
* @Descrition 移除文件
* @Param [file]
* @return void
*/
public void remove(AbstractFile file){
list.remove(file);
}
/**
* @MethodName getFile
* @Descrition 查找文件
* @Param [index]
* @return pri.xiaowd.composite.AbstractFile
*/
public AbstractFile getFile(int index){
return list.get(index);
}
public Folder(String name) {
this.name = name;
}
@Override
public void killVirus() {
System.out.println("查殺文件夾"+this.name);
for(AbstractFile f:list){
f.killVirus();
}
}
}
可以說組合模式的核心是在容器組件中定義了一個容器,同于存放其他的葉子組件和容器組件,在對組件執(zhí)行某一操作時,對于葉子組件直接訪問,對于容器組件會遍歷容器內(nèi)的所有組件(葉子組件直接訪問,容器組件進(jìn)行遞歸操作)。
測試:
/**
* @ClassName Client
* @Description 測試
* @Author xwd
* @Date 2018/10/24 22:49
*/
public class Client {
public static void main(String[] args) {
AbstractFile f1,f2,f3,f4,f5;
f1 = new ImageFile("美女.jpg");
f2 = new VideoFile("阿凡達(dá).mp4");
f3 = new Folder("電影");
f4 = new Folder("音樂");
f1.killVirus();
f2.killVirus();
f3.killVirus();
f4.killVirus();
((Folder) f3).add(f1);
((Folder) f3).add(f2);
((Folder) f4).add(f3);
f4.killVirus();
}
}

測試結(jié)果
四、組合模式的應(yīng)用場景
- 操作系統(tǒng)的資源管理器
- GUI中的容器層次圖
- XML文件解析
- OA系統(tǒng)中,組織結(jié)構(gòu)的處理
- Junit單元測試框架
- 底層設(shè)計(jì)就是典型的組合模式,TestCase(葉子)、TestUnite(容器)、Test接口(抽象)