?廊坊的風一如既往的在窗外刮著,天地間肆意地飄灑,縱情在一剎那,為何現在只剩下風吹亂我的發,亂蓬蓬的,還是去超市逛逛吧,買吃的`(*∩_∩*)′,走進華聯超市,熱情的店員招呼著我,開始為我介紹,推薦各種各樣商品,店員向我推薦了他們的會員卡,全場所有項目均八折,每逢節假日打五折,我心想那太劃算了,而且他們總店,分店,加盟店都可以用,所以就辦了張會員卡。今天我們的設計模式就從超市會員卡開始說起。
這個儼然就是我們設計模式中的組合模式----組合模式有時候又叫做部分-整體模式,它使我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以向處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。看下面的兩幅圖片:
? ? ? ? ? ??
上面兩幅圖片我們可以看做是一個文件結構,對于這樣的結構我們稱之為樹形結構。在《大話設計模式》中我們了解到可以通過調用某個方法來遍歷整個樹,當我們找到某個葉子節點后,就可以對葉子節點進行相關的操作。我們可以將這顆樹理解成一個大的容器,容器里面包含很多的成員對象,這些成員對象即可是容器對象也可以是葉子對象。但是由于容器對象和葉子對象在功能上面的區別,使得我們在使用的過程中必須要區分容器對象和葉子對象,但是這樣就會給客戶帶來不必要的麻煩,對于客戶而言,始終希望能夠一致的對待容器對象和葉子對象。這就是組合模式的設計動機:組合模式定義了如何將容器對象和葉子對象進行遞歸組合,使得客戶在使用的過程中無須進行區分,可以對他們進行一致的處理。下面一起來看一下組合模式的結構圖:
? ? ? ?
以上述在華聯超市辦會員卡為例,看看組合模式是如何在代碼中實現:
? ? ? ?
~~~
using?System;??
using?System.Collections.Generic;??
using?System.Linq;??
using?System.Text;??
using?System.Threading.Tasks;??
??
namespace?ConsoleApplication3??
{??
????class?Program??
????{??
????????static?void?Main(string[]?args)??
????????{??
????????????StoreOrBranch?store?=?new?StoreOrBranch("北京總店");??
????????????StoreOrBranch?brach?=?new?StoreOrBranch("廊坊分店");??
????????????JoinInStore?jstore?=?new?JoinInStore("安徽加盟店一");??
????????????JoinInStore?jstore1?=?new?JoinInStore("海南加盟店二");??
??
????????????brach.Add(jstore);??
????????????brach.Add(jstore1);??
????????????store.Add(brach);??
??
????????????store.PayByCard();??
????????}??
????}??
??
??
????///???
????///?店面類?抽象出來的店面部件??
????///???
????public?abstract?class?Storefront??
????{??
????????//店名??
????????protected?string?storeName?=?string.Empty;??
????????public?string?StoreName??
????????{??
????????????get??
????????????{??
????????????????return?storeName;??
????????????}??
????????}??
??
????????//添加店面??
????????public?abstract?void?Add(Storefront?store);??
????????//刪除店面??
????????public?abstract?void?Remove(Storefront?store);??
??
????????//定義所有部件公用的行為?刷卡行為??
????????public?abstract?void?PayByCard();??
????}??
??
????public?class?StoreOrBranch?:?Storefront??
????{??
????????//構造函數??
????????public?StoreOrBranch()?{?}??
????????public?StoreOrBranch(string?storeName)??
????????{??
????????????this.storeName?=?storeName;??
????????}??
????????List?myStoreList?=?new?List();??
????????//刷卡消費??
????????public?override?void?PayByCard()??
????????{??
????????????Console.WriteLine("店面{0}的積分已累加進該會員卡",?storeName);??
????????????foreach?(Storefront?sf?in?myStoreList)??
????????????{??
????????????????sf.PayByCard();??
????????????}??
????????}??
??
????????//增加店面??
????????public?override?void?Add(Storefront?store)??
????????{??
????????????myStoreList.Add(store);??
????????}??
??
????????//解除店面??
????????public?override?void?Remove(Storefront?store)??
????????{??
????????????myStoreList.Remove(store);??
????????}??
????}??
??
????public?class?JoinInStore?:?Storefront??
????{??
????????//構造函數??
????????public?JoinInStore()?{?}??
????????public?JoinInStore(string?storeName)??
????????{??
????????????this.storeName?=?storeName;??
????????}??
????????//刷卡消費??
????????public?override?void?PayByCard()??
????????{??
????????????Console.WriteLine("店面{0}的積分已累加進該會員卡",?storeName);??
????????}??
??
????????public?override?void?Add(Storefront?store)??
????????{?}??
??
????????public?override?void?Remove(Storefront?store)??
????????{?}??
????}??
??
?????
}??
~~~
組合模式的目的是:讓客戶端不再區分操作的是組合對象還是葉子對象,而是以一個統一的方式來操作。實現這個目標的關鍵之處,是設計一個抽象的組件類,讓它可以代表組合對象和葉子對象。這樣一來,客戶端就不用區分到底是組合對象還是葉子對象了,只需要全部當成組件對象進行統一的操作就可以了。