定義
迭代器模式提供一種方法順序訪問一個(gè)聚合對象中的各個(gè)元素,而又不暴露其內(nèi)部的表示.
組合模式允許你將對象組合成樹形來表現(xiàn)"整體/部分"的層次結(jié)構(gòu).組合能讓客戶以一致的方式處理個(gè)別對象和對象組合.
要點(diǎn)
- 迭代器允許訪問聚合的元素,而不需要暴露他的內(nèi)部結(jié)構(gòu).
- 迭代器將遍歷聚合的工作封裝進(jìn)一個(gè)對象中.
- 當(dāng)使用迭代器的時(shí)候,我們依賴聚合提供遍歷.
- 迭代器提供了一個(gè)通用的接口,讓我們遍歷聚合的項(xiàng),當(dāng)我們的編碼使用聚合的項(xiàng)時(shí),就可以使用多態(tài)機(jī)制.
- 我們應(yīng)該努力讓一個(gè)類只分配一個(gè)責(zé)任.
- 組合模式提供一個(gè)結(jié)構(gòu),可同時(shí)包容個(gè)別對象和組合對象.
- 組合模式允許客戶對個(gè)別對象以及組合對象一視同仁.
- 組合結(jié)構(gòu)內(nèi)的任意對象稱為組件,組件可以是組合,也可以是葉節(jié)點(diǎn).
- 在實(shí)現(xiàn)組合模式時(shí),有許多設(shè)計(jì)上的初衷.你要根據(jù)需要平衡透明性和安全性.
個(gè)人理解
迭代器模式
書中的各種不同菜單的數(shù)據(jù)存儲集合調(diào)用的時(shí)候確實(shí)頗為困難,我在前面學(xué)習(xí)設(shè)計(jì)的時(shí)候?qū)W習(xí)到了很多設(shè)計(jì)原則,其中很重要的有一點(diǎn)面向接口開發(fā),而不是面向?qū)崿F(xiàn)開發(fā)!那么如何寫才能使我們的上層調(diào)用變得既簡單,可維護(hù)性又高呢?
前期作者僅僅是針對集合這一個(gè)方面來闡述他的設(shè)計(jì)理念,如何讓上層調(diào)用者不用考慮菜單集合的具體實(shí)現(xiàn),同時(shí)又能夠提高可擴(kuò)展性來實(shí)現(xiàn)功能呢?作者給出了迭代器這個(gè)答案,JAVA中許多集合實(shí)際上是自身實(shí)現(xiàn)了迭代器的,這樣的做法其實(shí)在我看來,迭代器就相當(dāng)于使用適配器模式將菜單的接口進(jìn)行統(tǒng)一的適配,方便上層進(jìn)行調(diào)用.
更深層次的看下去,這樣的做法其實(shí)將上層(侍者)和菜單進(jìn)行了解耦,上層根本不知道菜單是如何實(shí)現(xiàn)的,同時(shí)侍者在創(chuàng)建迭代器的時(shí)候其實(shí)也利用了多態(tài),我們后期維護(hù)的時(shí)候在一定修改范圍內(nèi)這個(gè)模式是沒有問題的,但例如在菜單中插入子菜單那單單依靠迭代器模式已經(jīng)無法滿足需求了,下面我們來看看組合模式.
組合模式
組合模式利用下圖的這種樹形結(jié)構(gòu),這種結(jié)構(gòu)類似windows的文件夾結(jié)構(gòu),我們可以在任何時(shí)候在一個(gè)維度對這個(gè)集合進(jìn)行擴(kuò)展,我們可以添加一個(gè)具體的節(jié)點(diǎn),也可以添加一個(gè)對象聚合,如果這些添加的對象和聚合的接口全部是覆寫自父類的接口,那我們就可以像文中那樣一視同仁的對待每一個(gè)節(jié)點(diǎn),因?yàn)樗麄兌祭^承自一個(gè)父類,接口也是相同的.這個(gè)時(shí)候,我們可以很輕松的利用遞歸來完成對這個(gè)樹的遍歷,這是一種很巧妙地方式.
具體怎么做呢?我們可以在抽象類中寫出覆寫沒有用到所有的接口,在實(shí)現(xiàn)中讓他們?nèi)繏伋?code>異常,這在JAVA中是一種很常見的做法,當(dāng)然,我們在OC中這樣直接拋出異常的方法還是過于剛猛和直接,可以用其他一些委婉的做法.這里為什么要將父類全部覆寫上異常呢?原因比較簡單,繼承的子類并不是需要覆寫全部的接口的,那些不需要的接口,就直接使用父類的異常實(shí)現(xiàn)就好了,這樣表面上看起來葉節(jié)點(diǎn)和組合其實(shí)是一致的.
