一、引子
在大學的資料結構這門課上,樹是最重要的章節之一。還記得樹是怎麼定義的嗎?樹(Tree)是n(n≥0)個結點的有限集T,T為空白時稱為空白樹,否則它滿足如下兩個條件:
(1)
有且僅有一個特定的稱為根(Root)的結點;
(2)
其餘的結點可分為m(m≥0)個互不相交的子集Tl,T2,…,Tm,其中每個子集本身又是一棵樹,並稱其為根的子樹(SubTree)。
上面給出的遞迴定義刻畫了樹的固有特性:一棵非空樹是由若干棵子樹構成的,而子樹又可由若干棵更小的子樹構成。而這裡的子樹可以是葉子也可以是分支。
今天要學習的組合模式就是和樹型結構以及遞迴有關係。
二、定義與結構
組合(Composite)模式的其它翻譯名稱也很多,比如合成模式、樹模式等等。在《設計模式》一書中給出的定義是:將對象以樹形結構組織起來,以達成“部分-整體”的階層,使得用戶端對單個對象和組合對象的使用具有一致性。
從定義中可以得到使用組合模式的環境為:在設計中想表示對象的“部分-整體”階層;希望使用者忽略組合對象與單個對象的不同,統一地使用組合結構中的所有對象。
看下組合模式的組成。
1)
抽象構件角色Component:它為組合中的對象聲明介面,也可以為共有介面實現預設行為。
2)
樹葉構件角色Leaf:在組合中表示分葉節點對象——沒有子節點,實現抽象構件角色聲明的介面。
3)
樹枝構件角色Composite:在組合中表示分支節點對象——有子節點,實現抽象構件角色聲明的介面;儲存子組件。
為組合模式的類圖表示。
:一個Composite執行個體可以像一個簡單的Leaf執行個體一樣,可以把它傳遞給任何使用Component的方法或者對象,並且它表現的就像是一個Leaf一樣。可以看出來,使用組合模式使得這個設計結構非常靈活,在下面的例子中會得到進一步的印證。
三、安全性與透明性
組合模式中必須提供對子物件的管理方法,不然無法完成對子物件的添加刪除等等操作,也就失去了靈活性和擴充性。但是管理方法是在Component中就聲明還是在Composite中聲明呢?
一種方式是在Component裡面聲明所有的用來管理子類對象的方法,以達到Component介面的最大化。目的就是為了使客戶看來在介面層次上樹葉和分支沒有區別——透明性。但樹葉是不存在子類的,因此Component聲明的一些方法對於樹葉來說是不適用的。這樣也就帶來了一些安全性問題。
另一種方式就是只在Composite裡面聲明所有的用來管理子類對象的方法。這樣就避免了上一種方式的安全性問題,但是由於葉子和分支有不同的介面,所以又失去了透明性。
《設計模式》一書認為:在這一模式中,相對於安全性,我們比較強調透明性。對於第一種方式中葉子節點內不需要的方法可以使用空處理或者異常報告的方式來解決。
具體例子可以參考:http://www.cnblogs.com/webabcd/archive/2007/05/13/744865.html