標(biāo)簽: 設(shè)計(jì)模式初涉
描述性文字
組合模式,又稱為 部分整體模式,把具有相似的一組對象
當(dāng)做一個(gè)對象處理,用一種樹狀的結(jié)構(gòu)來組合對象,再提供統(tǒng)一
的方法去訪問相似的對象,以此忽略掉對象與對象容器間的差別。
舉個(gè)簡單例子,菜單和菜品,同樣是以小豬的奶茶店為例子:

假設(shè)這兩類需求如下:
菜單:菜單名,描述信息,添加,添加刪除子菜單或菜品
遞歸打印出所有的子菜單與菜品!
菜品:菜名,描述信息,價(jià)格,打印信息
好的,先試試不用組合模式,要怎么寫~
不使用組合模式寫菜單
1.先把四個(gè)菜品都創(chuàng)建出來,一樣的結(jié)構(gòu),名稱,描述,價(jià)格,打印:




2.創(chuàng)建菜單類,名稱,描述信息,可以增刪菜品,子菜單,遍歷打?。?/p>

3.客戶端調(diào)用

4.打印結(jié)果

好的,沒毛病,但是問題來了,如果增刪菜品或者子菜單,原有代碼
都要進(jìn)行相應(yīng)的修改,擴(kuò)展性差,如果引入組合模式會又會如何?
使用組合模式寫菜單
1.抽象出即可代表菜單又可代表菜品的類,這里我們只需要一個(gè)
add,get,getString三個(gè)抽象方法,讓菜單和菜品去繼承,菜品
只需完成getString方法重寫,菜單需要重寫add和get方法。

2.四個(gè)照葫蘆畫瓢的菜品類




3.菜單類

4.客戶端調(diào)用

5.打印結(jié)果

使用了合并模式,如果此時(shí)我們要新增一個(gè)菜品,只需繼承抽象構(gòu)建類,
無需改動其他類,顯得更加方便。
概念與總結(jié)
三個(gè)角色
上面也說了合并模式是用一種樹狀的結(jié)構(gòu)來組合對象,三個(gè)名詞
根節(jié)點(diǎn),枝結(jié)點(diǎn),葉子結(jié)點(diǎn),類比上面那個(gè)菜單的圖,
根節(jié)點(diǎn)是菜單,枝結(jié)點(diǎn)是飲料菜單和小吃菜單,
葉子結(jié)點(diǎn)是奶茶,果汁,手抓餅和魚蛋!
-
Component:抽象組件,為組合中的對象聲明接口,讓客戶端
可以通過這個(gè)接口來訪問和管理整個(gè)對象結(jié)構(gòu),可以在里面為定義的
功能提供缺省的實(shí)現(xiàn),比如上面的AbstractMenu類。 -
Composite:容器組件,繼承抽象組件,實(shí)現(xiàn)抽象組件中與
葉子組件相關(guān)的操作,比如上面的Menu類重寫了get,set方法。 -
Leaf:葉子組件,定義和實(shí)現(xiàn)葉子對象的行為,不再包含其它
的子節(jié)點(diǎn)對象,比如上面的MilkTea,Juice,HandCake,F(xiàn)ishBall。
UML類圖:

使用情景
- 如果你想表示對象的部分-整體層次結(jié)構(gòu),可以選用組合模式,
把整體和部分的操作統(tǒng)一起來,使得層次結(jié)構(gòu)實(shí)現(xiàn)更簡單,從外
部來使用這個(gè)層次結(jié)構(gòu)也簡單; - 如果你希望統(tǒng)一的使用組合結(jié)構(gòu)中的所有對象,可以選用組合
模式,這正是組合模式提供的主要功能;
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
讓客戶端更加簡單,客戶端不需要再操心面對的是組合對象還是葉節(jié)點(diǎn)
對象,所以不需要寫一大堆if語句來保證他們對正確的對象調(diào)用了正確
的方法。通常,他們只需要對整個(gè)結(jié)構(gòu)調(diào)用一個(gè)方法并執(zhí)行操作就可以了。
缺點(diǎn):
容易增加新的組件也會帶來一些問題,比如很難限制組合中的組件類型。
這在需要檢測組件類型的時(shí)候,使得我們不能依靠編譯期的類型約束來
完成,必須在運(yùn)行期間動態(tài)檢測。
本節(jié)代碼:
https://github.com/coder-pig/DesignPatternsExample/tree/master/8.Composite%20Pattern