定義:
- 將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

組合模式通用類圖
/*
* 創(chuàng)建抽象構(gòu)建
* */
public abstract class Component {
// 個(gè)體和整體共有的方法
public void doSomething() {
}
}
/*
* 創(chuàng)建樹枝組件
* */
public class Composite extends Component {
// 構(gòu)架容器
private ArrayList<Component> componentArrayList = new ArrayList<>();
public void add(Component component) {
this.componentArrayList.add(component);
}
public void remove(Component component) {
this.componentArrayList.remove(component);
}
public ArrayList<Component> getChildren() {
return this.componentArrayList;
}
}
/*
* 創(chuàng)建最小的組件
* */
public class Leaf extends Component {
@Override
public void doSomething() {
// TODO Auto-generated method stub
super.doSomething();
}
}
public class Client {
public static void main(String[] args) {
// 創(chuàng)建根節(jié)點(diǎn)
Composite root = new Composite();
// 創(chuàng)建樹枝節(jié)點(diǎn)
Composite branch = new Composite();
// 創(chuàng)建樹葉
Leaf leaf = new Leaf();// 違反依賴倒轉(zhuǎn)原則
root.add(branch);
branch.add(leaf);
}
// 遞歸遍歷節(jié)點(diǎn)
public static void display(Composite root) {
for (Component c : root.getChildren()) {
if (c instanceof Leaf) {
c.doSomething();
} else {
display((Composite) c);
}
}
}
}
優(yōu)點(diǎn):
- 高層模塊的調(diào)用簡單,所有的節(jié)點(diǎn)都是Component,局部和整體對(duì)調(diào)用者來說沒有任何區(qū)別,高層模塊不關(guān)心自己處理的是單個(gè)對(duì)象還是整個(gè)組合結(jié)構(gòu),簡化了高層模塊的代碼。
- 節(jié)點(diǎn)自由增加
缺點(diǎn):
- 定義時(shí)候直接使用的是實(shí)現(xiàn)類,這在面向接口編程上是很不恰當(dāng)?shù)模c依賴倒置原則沖突。
組合模式的拓展:
- 透明的組合模式(透明模式是把用來組合使用的方法放到抽象類中,通過判斷getChildren的返回值確認(rèn)是葉子節(jié)點(diǎn)還是書直接點(diǎn),如果處理不當(dāng),這個(gè)會(huì)在運(yùn)行期間出現(xiàn)問題):

透明模式的通用類圖
public abstract class Component {
public void doSomething() {
}
public abstract void add(Component component);
public abstract void remove(Component component);
public abstract ArrayList<Component> getChildren();
}
public class Leaf extends Component {
@Deprecated
public void add(Component component) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Deprecated
public void remove(Component component) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Deprecated
public ArrayList<Component> getChildren() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
}
public class Client {
public static void main(String[] args) {
}
public static void display(Component root) {
for (Component c : root.getChildren()) {
if (c instanceof Leaf) {
c.doSomething();
} else {
/*
* 不再使用強(qiáng)制類型轉(zhuǎn)換,遵循依賴倒轉(zhuǎn)原則
*/
display(c);
}
}
}
}
- 組合模式的遍歷(可以通過在節(jié)點(diǎn)中添加對(duì)應(yīng)的父節(jié)點(diǎn)對(duì)象信息,使得從子節(jié)點(diǎn)遍歷的時(shí)候可以查詢到相關(guān)的父節(jié)點(diǎn)信息)