組合模式(Composite Pattern)(一):組合模式介紹
一、意圖
將物件組合成樹形結構以表示“部分-整體”的層次結構。Composite模式使得使用者對單個物件和組合物件的使用具有一致性。
二、適用性
• 你想表示物件的部分-整體層次結構。
• 你希望使用者忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。
三、組成
——抽象構件角色(Component):為組合中的物件宣告介面, 在適當的情況下,也可實現所有類共有介面的預設行為。
——樹葉構件角色(Leaf):在組合中表示葉節點物件,沒有子節點,實現抽象構件角色宣告的介面。
——樹枝構件角色(Composite):在組合中表示分支節點物件,有子節點,實現抽象構件角色宣告的介面;儲存子部件。
四、兩種實現方式
——透明式的組合模式:將管理子構件的方法定義在Component介面中,這樣Leaf類就需要處理這些對其意義不大的方法(空實現或拋異常),在介面層次上Leaf和Composite沒有區別,即透明性。Component 宣告的這些管理子構件的方法對於Leaf來說是不適用的,這樣也就帶來了一些安全性問題。
——安全式的組合模式:將管理子構件的方法定義在Composite中,這樣編譯時任何從Leaf 中增加或刪除物件的嘗試都將被發現,但是由於Leaf和Composite有不同的介面(方法),又失去了透明性。
五、結構
六、簡單實現
將管理子構件的方法定義在Composite中,即安全式的組合模式
1.Component
public interface Component
{
public void doSomething();
}
2.Leaf
public class Leaf implements Component
{
@Override
public void doSomething()
{
System.out.println("Leaf doSomething");
}
}
3.Composite
public class Composite implements Component { List<Component> childs = new ArrayList<Component>(); public void add(Component child) { this.childs.add(child); } public void remove(Component child) { this.childs.remove(child); } public Component getChild(int i) { return this.childs.get(i); } @Override public void doSomething() { for (Component child : childs) child.doSomething(); } }
4.Client
public class Client
{
public static void main(String[] args)
{
/**
* composite1
* / \
* leaf1 composite2
* / \
* leaf2 leaf3
*
* */
Component leaf1=new Leaf();
Component leaf2=new Leaf();
Component leaf3=new Leaf();
Composite composite1=new Composite();
Composite composite2=new Composite();
composite2.add(leaf2);
composite2.add(leaf3);
composite1.add(leaf1);
composite1.add(composite2);
composite1.doSomething();
}
}
七、其他
1.組合模式讓我們能用樹形方式建立物件的結構,樹裡面包含了Composite以及Leaf的物件。使用組合結構,我們能把相同的操作應用在Composite和Leaf上,即大多數情況下,我們可以忽略Composite和Leaf之間的差別,以相同的方式使用它們。為了保持透明性,Leaf和Composite都要繼承或實現Component。
2.讓管理子構件的方法如add()、remove()、getChild()等出現在Leaf中,是因為我們可以將Leaf看作是沒有子構件的節點。
3.《設計模式》一書認為:在組合模式中,相對於安全性,我們比較強調透明性。對於透明式的組合模式中的Leaf內不需要的方法可以使用空處理或者異常報告的方式來解決。
4.Component中可以有一個指向父親的指標,以便在遊走時更容易。比如刪除樹形結構中的某個子樹或葉節點(即Composite或Leaf)時會更加方便。
轉載請註明出處:http://blog.csdn.net/jialinqiang/article/details/8946607