前言
????可以把組合體想象成為一個(gè)實(shí)體砌溺,它包含著同一類型的其它實(shí)體影涉。例如算術(shù)表達(dá)式,其包括操作數(shù)规伐、操作符和另一個(gè)操作數(shù)蟹倾,其中,另一個(gè)操作數(shù)也可以是操作數(shù)楷力、操作符和另一個(gè)操作數(shù)喊式。整個(gè)結(jié)構(gòu)就像由父節(jié)點(diǎn)實(shí)體和子節(jié)點(diǎn)實(shí)體連接而成的樹。它就像同一個(gè)祖先的族譜樹一樣萧朝,族譜中每個(gè)節(jié)點(diǎn)都有相同的姓岔留。假設(shè)詢問曾祖父(樹的根節(jié)點(diǎn)),請(qǐng)問家里幾口人检柬?操作將從樹根往下傳献联,樹中的每個(gè)有孩子的組合體會(huì)對(duì)孩子的總數(shù)與孩子們返回的數(shù)求和,然后將這個(gè)和返回何址。不必分別請(qǐng)求族譜樹中的每個(gè)成員里逆,可以向樹發(fā)送消息對(duì)其整體進(jìn)行操作。
????在面向?qū)ο筌浖O(shè)計(jì)中我們借用類似的思想用爪,組合結(jié)構(gòu)可以非常復(fù)雜原押,我們需要通過統(tǒng)一的接口把整個(gè)復(fù)雜結(jié)構(gòu)作為一個(gè)整體來(lái)使用,所以客戶端不必知道某個(gè)節(jié)點(diǎn)是什么就能夠使用它偎血。
什么是組合模式
????組合模式诸衔,又叫部分整體模式,將對(duì)象組合成樹形結(jié)構(gòu)以表示"部分-整體"的層次結(jié)構(gòu)颇玷,使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性笨农。什么是部分-整體的層次結(jié)構(gòu)呢?它是既包含對(duì)象的組合又包含作為葉節(jié)點(diǎn)的單個(gè)對(duì)象的一種層次結(jié)構(gòu)帖渠。每個(gè)組合體包含的其它節(jié)點(diǎn)谒亦,可以是葉節(jié)點(diǎn)或者是其它組合體,這種關(guān)系在這個(gè)層次結(jié)構(gòu)中遞歸重復(fù),因?yàn)槊總€(gè)組合或者葉節(jié)點(diǎn)具有相同的類型份招。下圖是運(yùn)行時(shí)組合對(duì)象結(jié)構(gòu)的一個(gè)例子:
組合模式的靜態(tài)結(jié)構(gòu)下類圖所示:
??? <Component>
定義了 Leaf
類和 Composite
類的共同操作切揭,組合模式使得客戶端可以統(tǒng)一處理 Leaf
和 Composite
對(duì)象。Leaf
和 Composite
的主要區(qū)別在于 Leaf
節(jié)點(diǎn)不包含同類型的子節(jié)點(diǎn)锁摔,而 Composite
則包含伴箩。 Composite
通過 add:Component
和 remove:Component
管理子節(jié)點(diǎn)。
什么時(shí)候使用組合模式
- 想獲得對(duì)象抽象的樹形表示
- 想讓客戶端忽略組合對(duì)象與單個(gè)對(duì)象的不同鄙漏,統(tǒng)一處理組合結(jié)構(gòu)中的所有對(duì)象。
組合模式的優(yōu)缺點(diǎn)
組合模式的優(yōu)點(diǎn)
- 高層模塊調(diào)用簡(jiǎn)單棺蛛。
- 節(jié)點(diǎn)自由增加怔蚌。
組合模式的缺點(diǎn)
在使用組合模式時(shí),其葉子和樹枝的聲明都是實(shí)現(xiàn)類旁赊,而不是接口桦踊,違反了依賴倒置原則。
Cocoa 中的組合模式
????在 Cocoa 中终畅,UIView
被組織成一個(gè)組合結(jié)構(gòu)籍胯,每個(gè) UIView
的實(shí)例可以包含 UIView
的其它實(shí)例,形成統(tǒng)一的樹形結(jié)構(gòu)离福。讓客戶端對(duì)單個(gè) UIView
對(duì)象和 UIView
的組合統(tǒng)一對(duì)待杖狼。
????窗口中的 UIView
在內(nèi)部形成視圖的樹形結(jié)構(gòu)。層次結(jié)構(gòu)的根部是一個(gè)窗口( UIWindow
對(duì)象)及其內(nèi)容視圖妖爷,一個(gè)填充窗口內(nèi)容矩形的透明視圖蝶涩。添加到內(nèi)容視圖的視圖成為它的子視圖,并且它們成為添加到它們的任何視圖的父視圖絮识。除了內(nèi)容視圖绿聘,一個(gè)視圖有一個(gè)(并且只有一個(gè))父視圖 和零或任意數(shù)量的子視圖〈紊啵可以將此結(jié)構(gòu)視為包含:父視圖包含其子視圖熄攘。
????視圖層次結(jié)構(gòu)是一種結(jié)構(gòu)體系結(jié)構(gòu),它在繪圖和事件處理中都起作用彼念。一個(gè)視圖有兩個(gè)邊界矩形挪圾,它的框架和它的邊界,這會(huì)影響視圖的圖形操作是如何發(fā)生的国拇÷迨罚框架是外部邊界;它在其父視圖的坐標(biāo)系中定位視圖酱吝,定義其大小也殖,并將繪圖剪輯到視圖的邊緣。bounds,內(nèi)部邊界矩形忆嗜,定義了視圖自身繪制的表面的內(nèi)部坐標(biāo)系己儒。
????當(dāng)窗口系統(tǒng)要求窗口準(zhǔn)備顯示時(shí),父視圖被要求在其子視圖之前呈現(xiàn)自己捆毫。當(dāng)向視圖發(fā)送一些消息時(shí)——例如闪湾,請(qǐng)求視圖重繪自身的消息——該消息被傳播到子視圖。因此绩卤,可以將視圖層次結(jié)構(gòu)的一個(gè)分支視為統(tǒng)一視圖途样。
總結(jié)
????組合模式的主要意圖是讓樹形結(jié)構(gòu)中的每個(gè)節(jié)點(diǎn)具有相同的抽象接口。這樣整個(gè)結(jié)構(gòu)可以作為一個(gè)統(tǒng)一的抽象結(jié)構(gòu)使用濒憋,而不暴露其內(nèi)部表示何暇。對(duì)每個(gè)節(jié)點(diǎn)的任何操作,可以通過協(xié)議或抽象基類中的相同接口來(lái)進(jìn)行凛驮。在 Cocoa 中裆站,UIView 視圖被組合成一個(gè)組合結(jié)構(gòu),思考一個(gè)問題黔夭,使用樹型結(jié)構(gòu)使得對(duì)應(yīng)視圖的數(shù)據(jù)被組合成一個(gè)組合結(jié)構(gòu)與其一一對(duì)應(yīng)實(shí)現(xiàn)動(dòng)態(tài)渲染...