介紹
組合模式(Composite Pattern) 也稱為部分-整體模式(Part-Whole Pattern) 結(jié)構(gòu)型設(shè)計(jì)模式之一
組合模式將一組相似的對象看作一個(gè)對象處理,并根據(jù)一個(gè)樹狀接口來組合對象,然后提供一個(gè)統(tǒng)一的方法去訪問相應(yīng)的對象,以此忽略掉對象與對象集合之間的差別。
組合模式中將一個(gè)擁有分支的節(jié)點(diǎn)稱之為枝干節(jié)點(diǎn),位于樹狀結(jié)構(gòu)頂部的枝干結(jié)構(gòu)比較特殊,我們稱為根結(jié)構(gòu)件,沒有分支的結(jié)構(gòu),稱之為葉子構(gòu)件
定義
將對象組合成樹形結(jié)構(gòu)以表示 “部分-整體” 的層次結(jié)構(gòu),使得用戶對單個(gè)對象和組合對象的使用具有一致性。
使用場景
- 表示對象的部分-整體層次結(jié)構(gòu)時(shí)
- 從一個(gè)整體中能夠獨(dú)立出部分模塊或功能的場景
角色介紹
Component 抽象根節(jié)點(diǎn),為組合中對象聲明接口,適當(dāng)情況下,實(shí)現(xiàn)所有類共有接口的缺省行為。聲明一個(gè)接口用于訪問和管理 Component 的子節(jié)點(diǎn),可在遞歸結(jié)構(gòu)中定義一個(gè)接口,用于訪問一個(gè)父節(jié)點(diǎn),并在合適的情況下實(shí)現(xiàn)它。
Composite 具體枝干節(jié)點(diǎn),定義有子節(jié)點(diǎn)的那些枝干節(jié)點(diǎn)的行為,存儲子節(jié)點(diǎn),實(shí)現(xiàn) Component 接口中定義的方法
Left 在組合中表示葉子節(jié)點(diǎn)對象,葉子節(jié)點(diǎn)沒有子節(jié)點(diǎn),在組合中定義節(jié)點(diǎn)對象的行為
Client 通過 Component 接口操縱組合節(jié)點(diǎn)的對象
將組合所使用的的方法定義在抽象類的方式稱為透明的組合模式,而上面所說的組合模式稱為安全的組合模式,透明組合模式中不管是葉子節(jié)點(diǎn)還是枝干節(jié)點(diǎn)都有著相同的結(jié)構(gòu),那意味著我們無法通過 getChilder 方法得到子節(jié)點(diǎn)的類型(安全的組合模式中葉子節(jié)點(diǎn)沒有 getchilder 方法),而必須通過內(nèi)部進(jìn)行判斷
實(shí)例
文件夾的管理,文件夾中可以存在文件夾和文件,抽象為組合模式
Android 開發(fā)中,目錄選擇器 DirSelector 會使用到組合模式
Android 源碼中的組合模式
View 和 ViewGroup 的嵌套組合就是安全的組合模式,只有 ViewGroup 才可以嵌套 View。
總結(jié)
Android 開發(fā)過程中組合模式適用于對一些界面 UI 的架構(gòu)設(shè)計(jì)上。這部分代碼絕大多數(shù)情況會由程序語言提供。
優(yōu)點(diǎn)
組合模式可以清楚地定義分層次的復(fù)雜對象,表示對象的全部或部分層次,它讓高層模塊忽略了層次的差異,方便對整個(gè)層次結(jié)構(gòu)進(jìn)行控制。
高層模塊可以一致地使用一個(gè)組合結(jié)構(gòu)或其中單個(gè)對象,不必關(guān)心處理的是單個(gè)對象還是整個(gè)組合結(jié)構(gòu),簡化了高層模塊的代碼
在組合模式中增加新的枝干構(gòu)件和葉子構(gòu)件都很方便,無須對現(xiàn)有的類庫進(jìn)行任何修改,符號“開閉原則”
組合模式為樹形結(jié)構(gòu)的面向?qū)ο髮?shí)例提供了一種靈活的解決方案,通過葉子對象和枝干對象的遞歸組合,可以形成復(fù)雜的樹形結(jié)構(gòu),但對樹形結(jié)構(gòu)的控制卻非常簡單
缺點(diǎn)
在新增構(gòu)件時(shí)不好對枝干中的構(gòu)件類型進(jìn)行限制,不能依賴類型系統(tǒng)來施加約束,因?yàn)樵诖蠖鄶?shù)情況下,它們都來自于相同的抽象層,此時(shí),必須在運(yùn)行時(shí)進(jìn)行類型檢查來實(shí)現(xiàn),這個(gè)實(shí)現(xiàn)過程比較復(fù)雜。