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

假設這兩類需求如下:
菜單:菜單名,描述信息,添加,添加刪除子菜單或菜品
遞歸打印出所有的子菜單與菜品!
菜品:菜名,描述信息,價格,打印信息
好的,先試試不用組合模式,要怎么寫~
不使用組合模式寫菜單
1.先把四個菜品都創建出來,一樣的結構,名稱,描述,價格,打?。?/p>




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

3.客戶端調用

4.打印結果

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

2.四個照葫蘆畫瓢的菜品類




3.菜單類

4.客戶端調用

5.打印結果

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

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