定義:組合模式也稱整體-部分模式,它的宗旨是通過將單個對象(葉子節點)和組合對象(樹枝節點)用相同接口進行表示。
作用:
使客戶端對當個對象和組合對象保持一致的方式處理。
適用場景:
1. 希望客戶端可以忽略組合對象與單個對象的差異時。
2. 對象層次具備整體和部分,如(樹形結構,樹形菜單,操作系統目錄等)。實例代碼:
/**
* 所有文件的根節點
*/
public abstract class Root {
protected String name;
public Root(String name) {
this.name = name;
}
abstract void show();
}
/**
* 文件夾
*/
public class Folder extends Root{
private Integer level;
private List<Root> child;
public Folder(String name, Integer level) {
super(name);
this.level = level;
child = new ArrayList<Root>();
}
@Override
void show() {
System.out.println(this.name);
for (Root root : this.child) {
//控制顯示格式
if (this.level != null) {
for (int i = 0; i < this.level; i++) {
//打印空格控制格式
System.out.print(" ");
}
for (int i = 0; i < this.level; i++) {
//每一行開始打印一個+號
if (i == 0) {
System.out.print(" + ");
}
System.out.print("-");
}
}
//打印名稱
root.show();
}
}
public boolean addChild(Root root){
return child.add(root);
}
public boolean removeChild(Root root){
return child.remove(root);
}
}
/**
* 文件
*/
public class File extends Root {
public File(String name) {
super(name);
}
@Override
void show() {
System.out.println(this.name);
}
}
public class Test {
public static void main(String[] args) {
Folder home = new Folder("home", 2);
Folder usr = new Folder("usr", 2);
home.addChild(new File("home1"));
home.addChild(new File("home2"));
home.addChild(new Folder("homeFolder1", 3));
usr.addChild(new File("usr1"));
usr.addChild(new File("usr2"));
Folder usrFolder1 = new Folder("usrFolder1", 3);
usrFolder1.addChild(new File("usrFolderChild1"));
File usrFolderChild2 = new File("usrFolderChild2");
usrFolder1.addChild(usrFolderChild2);
usrFolder1.removeChild(usrFolderChild2);
usr.addChild(usrFolder1);
Folder root = new Folder("root", 1);
root.addChild(home);
root.addChild(usr);
root.show();
}
}
結果:
root
+ -home
+ --home1
+ --home2
+ --homeFolder1
+ -usr
+ --usr1
+ --usr2
+ --usrFolder1
+ ---usrFolderChild1
類圖:
上述代碼展示了一個linxu文件目錄結構,我們可以通過組合模式非常方便的去擴展文件,而忽略了文件層次之間的差異。
優點:
1. 清除地定義分層次的複雜對象,表示對象額全部或部分層次。
2. 讓客戶端忽略了層次的差異,方便對整個層次結構進行控制。
3. 簡化客戶端代碼。
4. 符合開閉原則。
缺點:
1. 限制類型時會比較複雜。
2. 使設計變得更加抽象。