設計模式(12) 組合模式(簡單入門 結構模式)

From Now On,Let us begin Design Patterns。

組合模式

定義

  • 將對象組合成樹形結構以表示‘部分-整體’的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。 Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.

通用類圖:
這裏寫圖片描述

從定義中可以得到使用組合模式的環境爲:在設計中想表示對象的“部分-整體”層次結構;希望用戶忽略組合對象與單個對象的不同,統一地使用組合結構中的所有對象。

角色說明:
抽象構件角色Component:它爲組合中的對象聲明接口,也可以爲共有接口實現缺省行爲。

樹葉構件角色Leaf:在組合中表示葉節點對象——沒有子節點,實現抽象構件角色聲明的接口。

樹枝構件角色Composite:在組合中表示分支節點對象有子節點,實現抽象構件角色聲明的接口;存儲子部件。

透明性還是安全性:
組合模式中必須提供對子對象的管理方法,不然無法完成對子對象的添加刪除等等操作,也就失去了靈活性和擴展性。但是管理方法是在Component中就聲明還是在Composite中聲明呢?
一種方式是:在Component裏面聲明所有的用來管理子類對象的方法,以達到Component接口的最大化。目的就是爲了使客戶看來在接口層次上樹葉和分支沒有區別——透明性。但樹葉是不存在子類的,因此Component聲明的一些方法對於樹葉來說是不適用的。這樣也就帶來了一些安全性問題。
另一種方式就是:只在Composite裏面聲明所有的用來管理子類對象的方法。這樣就避免了上一種方式的安全性問題,但是由於葉子和分支有不同的接口,所以又失去了透明性。

《設計模式》一書認爲:在這一模式中,相對於安全性,我們比較強調透明性。對於第一種方式中葉子節點內不需要的方法可以使用空處理或者異常報告的方式來解決。最終我們選擇透明性。

組合模式優點:

  • 高層模塊調用簡單:樹形機構中所有節點都是Component,高層模塊不必關心自己處理的是單個對象還是整個組合結構,簡化了高層模塊的代碼

  • 更容易在組合體內加入對象部件. 客戶端不必因爲加入了新的對象部件而更改代碼。這一點符合開閉原則的要求,對系統的二次開發和功能擴展很有利,我們需要的構件可以直接在葉子節點加入

  • 節點自由增加:容易擴展,符合OCP,對維護有利

組合模式的缺點:

  • 有利必有弊,視需求而定:組合模式不容易限制組合中的構件,葉子節點可能會實現其他的方法。

  • 葉子節點的數量可能會很多。

組合模式的使用場景:

維護和展示部分-整體關係的場景,如樹形菜單、文件和文件夾管理

當發現需求中是體現部分與整體層次結構時,以及你希望用戶可以忽略組合對象與單個對象的不同,統一地使用組合結構中的所有對象時,就應該考慮組合模式了。

從一個整體中能夠獨立出部分模塊或功能的場景

注意事項:

Operation()函數可以配合迭代器模式一起使用。

組合模式的例子:會員卡消費

首先:
1.我們的部件有,總店,分店,加盟店!
2.我們的部件共有的行爲是:刷會員卡
3.部件之間的層次關係,也就是店面的層次關係是,總店下有分店、分店下可以擁有加盟店。
有了我們這幾個必要條件後,我的要求就是目前店面搞活動當我在總店刷卡後,就可以累積相當於在所有下級店面刷卡的積分總額,設計的代碼如下:

類圖:
這裏寫圖片描述

總店:抽象類,提供統一操作:
這裏寫圖片描述

分店:下面可以有加盟店
這裏寫圖片描述

加盟店:葉子節點,下面不可以有其他分店
這裏寫圖片描述

實現場景:
這裏寫圖片描述

運行結果:
這裏寫圖片描述

這樣在累積所有子店面積分的時候,就不需要去關心子店面的個數了,也不用關係是否是葉子節點還是組合節點了,也就是說不管是總店刷卡,還是加盟店刷卡,都可以正確有效的計算出活動積分。

發佈了60 篇原創文章 · 獲贊 41 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章