天天看點

【設計模式系列】結構型模式之Composite模式

概要 具備一系列既有獨立功能,又需要排列組合其中的幾種功能來達成一些複合的新功能時,可以采用組合模式。比如說,你設計了一個備份子產品,有email備份,note備份,message備份,log備份等一系列備份功能,而你又會需要同時備份它們中間不定的幾種時,考慮用組合模式吧。它能組合對象處理,而又不增加額外的耦合,并保證接口一緻,以及子產品的易用性和擴充性。

目的 自由組合既有對象處理來實作複合對象,保證單一對象和複合對象具有統一的對外接口。

執行個體 Command模式應該都比較熟悉了,這裡結合Command模式來舉個例子。 有時我們會把行為(action)封裝為類,比如我們需要如下這些action,儲存action,備份action,發送action,顯示action等,那麼考慮用Command模式來進行封裝,如下所示:

【設計模式系列】結構型模式之Composite模式

class CommandAction { public: virtual void Execute (); }; class SaveAction : public CommandAction { public: virtual void Execute (); }; class BackupAction : public CommandAction { public: virtual void Execute (); }; class SendAction : public CommandAction { public: virtual void Execute (); }; ......

我們有需要實作幾種複合行為,Composite1是(儲存+備份)action,Composite2是(儲存+顯示)action,Composite3是(儲存+顯示+發送)action,不要告訴我你會如下這樣去實作!為每種複合行為都設計一個類?

【設計模式系列】結構型模式之Composite模式

class CommandAction { public: virtual void Execute (); }; class Composite1: public CommandAction { public: ...... virtual void Execute () { mSave->Execute(); mBackup->Execute(); } private: SaveAction* mSave; BackupAction * mBackup; };

(省略Composite2, Composite3) 很容易看出,這不是一種好方法,擴充性太差,增加了類間的耦合度。如果又需要更多的不同的複合行為,難道再繼續追加類?太複雜,太煩了,子產品維護者看到這種設計會瘋掉的。 那麼,讓我們看看如果用Composite模式是怎麼解決的。

【設計模式系列】結構型模式之Composite模式

class CommandAction { public: virtual void Execute() = 0; virtual void AddAction(CommandAction* action); virtual void DeleteAction(CommandAction* action); }; class CompositeAction { public: ...... virtual void Execute() { list<CommandAction*>::iterator it; for (it = mCompositor.begin(); it != mCompositor.end(); it++) { if (*it != NULL) { (*it)->Execute(pack); } } } virtual void AddAction(CommandAction* action) { if (action != NULL) { mCompositor.push_back(action); } } virtual void DeleteAction(CommandAction* action) { list<CommandAction*>::iterator it; if (action != NULL) { for (it = mCompositor.begin(); it != mCompositor.end(); it++) { if (*it == action) { mCompositor.erase(it); break; } } } private: list<CommandAction*> mCompositor; };

設計一個CompositeAction類,具有跟其他Action統一的接口(Execute),CompositeAction包含一個基類CommandAction的list容器對象,通過AddAction和DeleteAction,可以由Client調用方自由追加和删除複合對象中需要包含的Action,而Execute方法會執行list中push進來的所有Action。

應用 在檔案系統庫中,存儲檔案節點包含檔案夾和檔案的組合,而一些UI庫中,複雜的UI也經常會由很多可定制的基本UI組成,當然相關應用還有很多,在這些庫中,Composite模式經常會被使用。另外Composite模式也經常跟Decorator模式結合起來使用,關于Decorator模式,在下一單元會有詳細的說明。

繼續閱讀