組合模式(Composite),將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示‘部分-整體’的層次結(jié)構(gòu)。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。
適用場(chǎng)景
需求中是體現(xiàn)部分與整體層次的結(jié)構(gòu)是,以及你希望用戶可以忽略組合對(duì)象與單個(gè)對(duì)象的不通過(guò),統(tǒng)一地使用組合結(jié)構(gòu)中的所有對(duì)象時(shí),就應(yīng)該考慮用組合模式了。
優(yōu)點(diǎn)
- 高層模塊調(diào)用簡(jiǎn)單。一棵樹(shù)形機(jī)構(gòu)中的所有節(jié)點(diǎn)都是Component,局部和整體對(duì)調(diào)用者來(lái)說(shuō)沒(méi)有任何區(qū)別,也就是說(shuō),高層模塊不必關(guān)心自己處理的是單個(gè)對(duì)象還是整個(gè)組合結(jié)構(gòu),簡(jiǎn)化了高層模塊的代碼。
- 節(jié)點(diǎn)自由增加。使用了組合模式后,增加一個(gè)樹(shù)枝節(jié)點(diǎn)、樹(shù)葉節(jié)點(diǎn)變得非常容易,只要找到它的父節(jié)點(diǎn)就成,非常容易擴(kuò)展,符合開(kāi)閉原則,對(duì)以后的維護(hù)非常有利。
缺點(diǎn)
組合模式有一個(gè)非常明顯的缺點(diǎn),看到我們?cè)诳蛻舳苏{(diào)用中的定義,提到樹(shù)葉和樹(shù)枝使用時(shí)的定義了嗎?直接使用了實(shí)現(xiàn)類!這在面向接口編程上是很不恰當(dāng)?shù)模c依賴倒置原則沖突,讀者在使用的時(shí)候要考慮清楚,它限制了你接口的影響范圍。
UML結(jié)構(gòu)圖

CompositePattern
源碼
Component:組合對(duì)象抽象類
/**
* 組合對(duì)象抽象類
*
* Created by zhenguo on 11/30/14.
*/
public abstract class Component {
protected String name;
public Component(String name) {
this.name = name;
}
public abstract void add(Component component);
public abstract void remove(Component component);
public abstract void display(int depth);
protected String getDepthStr(int depth) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < depth; i++) {
sb.append("-");
}
return sb.toString();
}
}
Leaf:葉子節(jié)點(diǎn),無(wú)子節(jié)點(diǎn)
/**
* 葉子節(jié)點(diǎn),無(wú)子節(jié)點(diǎn)
*
* Created by zhenguo on 11/30/14.
*/
public class Leaf extends Component {
public Leaf(String name) {
super(name);
}
@Override
public void add(Component component) {
System.out.println("Cannot add to a leaf!");
}
@Override
public void remove(Component component) {
System.out.println("Cannot remove to a leaf!");
}
@Override
public void display(int depth) {
System.out.println(getDepthStr(depth) + name);
}
}
Composite:子節(jié)點(diǎn)
/**
* 子節(jié)點(diǎn)
*
* Created by zhenguo on 11/30/14.
*/
public class Composite extends Component {
private List<Component> children = new ArrayList<Component>();
public Composite(String name) {
super(name);
}
@Override
public void add(Component component) {
children.add(component);
}
@Override
public void remove(Component component) {
children.remove(component);
}
@Override
public void display(int depth) {
System.out.println(getDepthStr(depth) + name);
for (Component component : children) {
component.display(depth + 2);
}
}
}
Client:客戶端調(diào)用
/**
* 客戶端調(diào)用
* 組合模式(Composite),將對(duì)象組合成樹(shù)形結(jié)構(gòu)以表示‘部分-整體’的層次結(jié)構(gòu)。組合模式使得用戶
* 對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。
*
* Created by zhenguo on 11/30/14.
*/
public class Client {
public static void main(String[] args) {
Composite root = new Composite("root");
root.add(new Leaf("Leaf A"));
root.add(new Leaf("Leaf B"));
Composite composite = new Composite("Composite X");
composite.add(new Leaf("Leaf XA"));
composite.add(new Leaf("Leaf XB"));
root.add(composite);
Composite composite1 = new Composite("Composite XY");
composite1.add(new Leaf("Leaf XYA"));
composite1.add(new Leaf("Leaf XYB"));
composite.add(composite1);
root.add(new Leaf("Leaf C"));
Leaf leaf = new Leaf("Leaf D");
root.add(leaf);
root.remove(leaf);
root.display(1);
}
}
設(shè)計(jì)模式系列:
| 創(chuàng)建型 | 結(jié)構(gòu)型 | 行為型 |
|---|---|---|
|
工廠方法 簡(jiǎn)單工廠 抽象工廠 建造者模式 單例模式 原型模式 |
組合模式 外觀模式 橋接模式 代理模式 享元模式 適配器模式 裝飾模式 |
策略模式 模板方法 狀態(tài)模式 觀察者模式 備忘錄模式 迭代器模式 命令模式 職責(zé)鏈模式 解釋器模式 訪問(wèn)者模式 中介者模式 |