概要
又是一種比較常見也比較常用的模式。系統模組經常需要進行功能上的擴充套件,比如下面這種形式的結構,
當需要擴充套件新function時,通常會通過繼承追加新類來實現功能的擴充套件。但是如果我們不是擴充套件乙個新功能的物件,而只是對
所有現有的每種功能類的處理進行擴充套件時,我們應該怎麼做?
decorator模式可以很好的解決這類問題。
目的
為一系列物件動態追加(或刪除)額外的功能,並保證統一的外部介面
例項
考慮這樣乙個比較典型的例子吧。ui中會用到很多種的window,比如對話方塊,選單,tab視窗,樹狀視窗等。
如果有需求需要追加這樣的功能:為每種window控制項都追加在window框中顯示某個logo的功能,怎麼解決?
最笨的方法:每種window都加這種功能,通過isshowlogo變數來決定是否顯示logo,
class basewin ;
class tabwin : public basewin
......
}};class treewin : public basewin
......
}};......
每種window都要改,太麻煩了,我想每個開發者都不會願意這樣去擴充套件。也許有人會說,上面的方法還可以稍微改善一下,比如說把顯示logo的處理都放在基類來進行:
class basewin
winshow();
}virtual void winshow();
virtual void displaylogo();
protected:
bool misshowlogo;
};class tabwin : public basewin ;
class treewin : public basewin ;
......
但是首先這樣會涉及到對基類和子類呼叫方式的調整,其次把logo顯示的處理跟原來的處理耦合在一起會帶來額外的風險,同時如果又需要對這些window再統一新增其他功能時又會涉及到再次的複雜的改動,擴充套件性比較差。
那麼讓我們進入正題,還是看看
decorator模式怎麼解決的。
};從basewin類繼承新增decoratorwin類,它包含乙個指向basewin物件的指標,它的show方法呼叫mwin指向的basewin物件的show方法。具體擴充套件時再從decoratorwin類繼承來實現,比如logwin類實現了顯示logo的方法,並在show方法中呼叫顯示logo方法。當然對介面使用client端來說是不用關心內部處理的,因為它們都具有統一的外部介面。如下所示是client端呼叫帶有logo顯示的tabwin的處理。
basewin* tab = new tabwin();
basewin* logo = new logwin(tab);
logo->show();
這樣的擴充套件有什麼好處呢?第一,改動範圍小,而且不需要調整原有的**,變更風險小;第二,可擴充套件性強,模組靈活性強;第三;擴充套件類具有跟原來一致的外部介面。
應用
decorator除了可以追加功能外,也可以統一去剝離現有的部分功能。當然由於decorator模式是在執行時動態的改變物件職責,所以也會給除錯增加一定難度。從目前已知應用來看,使用時相當廣泛的,比如對一些iostream的封裝和擴充套件,而在gui工具庫中decorator模式的使用的是最多的。另外,也要區分清楚adapter模式和decorator模式的區別,adapter模式改變的是物件的介面,而decorator改變的是物件的功能。
設計模式攻略 結構型模式之Adapter模式
概要 adapter模式,中文名為介面卡模式,從字面意思來看不難理解,就是通過模組,介面的包裝和適配達到模組介面相容協作的目的。這算是乙個很簡單的模式,就算你從來沒看過設計模式,從未聽說過adapter模式,聽我後面的介紹後,也許你會很不屑的說,早在我之前設計過的n個專案中,用過這種所謂的adapt...
設計模式之結構型模式
結構型設計模式主要考慮的是 如何組合類和物件以獲得更大的結構。結構型模式分為兩種 結構型物件模式和結構型類模式 結構型類行為模式 採用繼承機制來組合介面或實現。乙個簡單的例子是採用多重繼承方法將兩個以上的類組合成乙個類,結果這個類包含了所有父類的性質。eg adapter模式 結構型物件行為模式 描...
設計模式之結構型模式
設計模式分為三大類 1 建立型模式,共五種 工廠方法模式 抽象工廠模式 單例模式 建造者模式 原型模式。2 結構型模式,共七種 介面卡模式 裝飾器模式 模式 外觀模式 橋接模式 組合模式 享元模式。3 行為型模式,共十一種 策略模式 模板方法模式 觀察者模式 迭代子模式 責任鏈模式 命令模式 備忘錄...