組合模式(Composite Pattern),又叫部分整體模式,是用于把一組相似的對象當作一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及整體層次。這種類型的設計模式屬于結構型模式,它創(chuàng)建了對象組的樹形結構。
這種模式創(chuàng)建了一個包含自己對象組的類。該類提供了修改相同對象組的方式。
介紹
意圖:將對象組合成樹形結構以表示"部分-整體"的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。
主要解決:它在我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以像處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。
何時使用: 1、您想表示對象的部分-整體層次結構(樹形結構)。 2、您希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結構中的所有對象。
如何解決:樹枝和葉子實現統(tǒng)一接口,樹枝內部組合該接口。
關鍵代碼:樹枝內部組合該接口,并且含有內部屬性 List,里面放 Component。
應用實例: 1、算術表達式包括操作數、操作符和另一個操作數,其中,另一個操作數也可以是操作數、操作符和另一個操作數。 2、在 JAVA AWT 和 SWING 中,對于 Button 和 Checkbox 是樹葉,Container 是樹枝。
優(yōu)點: 1、高層模塊調用簡單。 2、節(jié)點自由增加。
缺點:在使用組合模式時,其葉子和樹枝的聲明都是實現類,而不是接口,違反了依賴倒置原則。
使用場景:部分、整體場景,如樹形菜單,文件、文件夾的管理。
注意事項:定義時為具體類。
代碼實現
//文件類
public abstract class File {
String name;
public File(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void display();
}
//文件夾類
public class Folder extends File {
private List<File> files;
public Folder(String name) {
super(name);
files = new ArrayList<>();
}
/**
* 【瀏覽文件夾中的文件】
*/
@Override
public void display() {
for (File file : files) {
file.display();
}
}
/**
* @param file
* @return void
* @desc 向文件夾中添加文件
*/
public void add(File file) {
files.add(file);
}
/**
* @param file
* @return void
* @desc 從文件夾中刪除文件
*/
public void remove(File file) {
files.remove(file);
}
}
// 然后是三個文件類:TextFile.java、ImageFile.java、VideoFile.java
public class ImagerFile extends File {
public ImagerFile(String name) {
super(name);
}
public void display() {
System.out.println("這是圖像文件,文件名:" + super.getName());
}
}
public class TextFile extends File {
public TextFile(String name) {
super(name);
}
@Override
public void display() {
System.out.println("這是文本文件,文件名:" + super.getName());
}
}
public class VideoFile extends File{
public VideoFile(String name) {
super(name);
}
public void display() {
System.out.println("這是影像文件,文件名:" + super.getName());
}
}
//客戶端
public class Client {
public static void main(String[] args) {
//總文件夾
Folder zwjj = new Folder("總文件夾");
//向總文件夾中放入三個文件:1.txt、2.jpg、1文件夾
TextFile aText= new TextFile("a.txt");
ImagerFile bImager = new ImagerFile("b.jpg");
Folder cFolder = new Folder("C文件夾");
zwjj.add(aText);
zwjj.add(bImager);
zwjj.add(cFolder);
//向C文件夾中添加文件:c_1.txt、c_1.rmvb、c_1.jpg
TextFile cText = new TextFile("c_1.txt");
ImagerFile cImage = new ImagerFile("c_1.jpg");
VideoFile cVideo = new VideoFile("c_1.rmvb");
cFolder.add(cText);
cFolder.add(cImage);
cFolder.add(cVideo);
//遍歷C文件夾
cFolder.display();
//將c_1.txt刪除
cFolder.remove(cText);
System.out.println("-----------------------");
cFolder.display();
}
}