設計模式之迭代器與組合模式(三)

  • 2019 年 12 月 25 日
  • 筆記

現在我們已經能愉快地看著一頁一頁羅列出來的菜單進行點菜了。現在又有的小夥伴希望能夠加上一份餐後甜點的「子菜單」。怎麼辦呢?我們不僅僅要支援多個菜單,甚至還要支援菜單中的菜單。

如果我們能讓甜點菜單變成餐廳菜單集合的一個元素,那該有多好。但是根據現在的實現,根本做不到呀。我們想要的是這樣的:

我們需要什麼

現在我們遇到的現實問題是,我們的系統已經達到了一個複雜的級別,如果現在不重新設計,就無法容納未來增加的菜單或子菜單等需求。

所以,在我們的新設計中,真正需要些什麼呢?

  • 我們需要某種樹形結構,可以容納菜單、子菜單和菜單項
  • 我們需要確定能夠在每個菜單的各個項之間遊走,而且至少要像現在用迭代器一樣方便
  • 我們也需要能夠更有彈性地在菜單項之間遊走。比方說,可能只需要遍歷甜點菜單,或者可以遍歷餐廳的整個菜單(包括甜點菜單在內)。

定義組合模式

沒錯,我們要介紹另一個模式解決這個難題。我們並沒有放棄迭代器–它仍然是我們解決方案中的一部分–然而,管理菜單的問題已經到了一個迭代器無法解決的新維度。所以,我們將倒退幾步,改用組合模式來實現。

組合模式:允許你將對象組合成樹形結構來表現「整體/部分」層次結構。組合能讓客戶以一致的方式處理個別對象以及對象組合。

讓我們以菜單為例思考這一切:這個模式能夠創建一個樹形結構,在同一個結構中處理嵌套菜單和菜單項組。通過將菜單和項放在相同的結構中,我們創建了一個「整體/部分」層次結構,即由菜單和菜單項組成的對象樹。但是可以將它視為一個整體,像是一個豐富的大菜單。

一旦有了豐富的大彩蛋,我們就可以使用這個模式來「統一處理個別對象和組合對象」。這意味著什麼?它意味著,如果我們有了一個樹形結構的菜單、子菜單和可能還帶有菜單項的子菜單,那麼任何一個菜單都是一種「組合」。

因為它既可以包含其他菜單,也可以包含菜單項。個別對象只是菜單項–並未持有其他對象。就像你將看到,使用一個遵照組合模式的設計,讓我們能夠寫出簡單的程式碼,就能夠對整個菜單結構應用相同的操作。

結合圖來描述如下:

組合模式的類圖如下:

了解完組合模式的種種,在下次的推文中,我們將用於實際操作。我們利用組合模式設計菜單,並且使用菜單,以此來鞏固加深。敬請期待吧。

愛生活,愛學習,愛感悟,愛挨踢