組合模式引導篇及組合模式原理java
在上一個《迭代器模式》中,咱們講到了阿里收購網易考拉後,店鋪合併的問題使用到了迭代器模式。如今又有了新需求。咱們先來看看新需求:設計模式
先說明:組合模式並不是是把以前學過的設計模式組合在一塊兒的一種模式哈。別理解錯了。數組
來源:凱哥Java(kaigejava)數據結構
在原有菜單的基礎上,新增餐後甜點功能,如在中餐廳(DinerMenu)中添加餐後甜點。ide
咱們先來回顧下上一個模式下的類圖,以下圖:spa
從上圖中,咱們能夠知道,服務員手裏拿的菜單遙控器,只是三個iterator 迭代器接口對象。設計
方案一:也是正常的,最容易想到的方案。orm
在DinerMenu菜單後面再追加一個子項,用來表示甜點的菜單。若是,咱們這樣寫了。其實最後,仍是使用的迭代器模式的。本篇,咱們講解的是組合模式。因此,咱要玩點高大上的。咱使用組合模式來實現這個需求。對象
咱們還能夠這麼想,將甜點設計成一個數據結構,而後將這個數據結構,放到中餐廳菜單的其中一個菜單下,讓甜點菜單成爲其子菜單。類圖以下:繼承
當咱們點擊dinnerMenu的第三個item的是,會彈出submenu,這樣形式。
若是要實現,上面形式的數據結構,那麼咱們原有系統會遇到的問題:
一:數據結構怎麼設計?怎麼遍歷獲取每個?
再上一個模式中,咱們知道,不管是List<Item>(cakeHouseMenu)、數組結構(DinerMenu)仍是hashTable結構的(cafeMenu)每個菜單都是一個item對象。這樣好遍歷,可是如今的是有些item下面帶有子菜單,這個怎麼遍歷出來?有的是item菜單項,有的是帶有子菜單,由於數據類型不一樣的這是個問題。
由於涉及到了子菜單,也就有了父子關係的。再咱們數據結構中,存在父子關係的,最早能想到的就是樹這種結構了。因此,咱們能夠抽象的畫出類圖:
咱們使用樹形結構,節點是菜單或子菜單,葉子是菜單項,須要可以在各個菜單項之間遊走,遍歷。要可以有彈性的在菜單項之間遊走。
從上圖中,咱們能夠看出,在抽出一個超類,讓葉子和含有葉子的節點都繼承或實現這個超類。把原來存放item的都替換成抽出的超類,這樣,整個體系中的數據類型都是同一個了。具體的,好比數組、list或者hashTable存放超類的子類。如,只放item的,咱們就只放菜單項,還有甜點的,咱們就放子菜單的。這樣存儲就統一了。
其實,組合模式的原理就是這樣的。
凱哥我的博客:www.kaigejava.com
什麼是組合模式:
組合模式又能夠叫作部分-總體模式。是用於把一組相似的對象看成一個單一的對象。組合模式依據的是樹形結構來組合對象,用來表示「部分或者是總體」的層次。
理解:
用於把一組相似的對象看成一個單一的對象什麼意思呢?如咱們的單個菜單項和帶有子菜單的菜單項,這兩個實際上是一組相似的對象。咱們再提供給服務員的時候,無論是單個菜單項仍是帶有子菜單的菜單項,對於服務員來講都是一個單一的對象。這下理解了吧。
用來表示部分以及總體層次怎麼理解?請看下圖:
其中部分是超類的子類,總體也是超類的這類,因此,咱們在處理的時候,不管是子類仍是總體都看做是單一的超類。
因此,咱們能夠獲得組合模式其實須要解決的問題是:能讓客戶以一致的方法來處理個別對象以及對象組合的。簡單理解就是:組合模式解決的問題是咱們能夠忽略對象組合與個體對象之間的差異的。
咱們來看看,在組合模式下,新需求的類圖:
從類圖中,咱們能夠看到,cakeHouseMenu繼承於MenuComponent對象;cakeHouseMenu下面的item也是繼承於MenuComponent對象。
本篇文章花了大量口舌來說解組合模式原理,但願你們可以更好的理解原理。在下一篇文章中,咱們將使用代碼來實現。