裝飾,字面意思是對生活用品或生活環境進行藝術加工的手法。它必須與所裝飾的客體有機地結合,成為統一、和諧的整體,以便豐富藝術形象,擴大藝術表現力,加強審美效果,并提高其功能、經濟價值和社會效益。我們程式設計世界中的裝飾又有着怎樣與衆不同的解釋呢?原來裝飾模式是在不必改變原類檔案和使用繼承的情況下,動态地擴充一個對象的功能。它是通過建立一個包裝對象,也就是裝飾來包裹真實的對象。
我們來看一個具體的例子,經過一個上午的消耗,加上昨天晚上熬夜看《出彩中國人》,早上賴床,沒有去吃飯,那上午叫一個餓啊,于是發誓,再也不熬夜了,咳咳,到了晚上,拿起手機什麼又都忘了,于是,想着趕緊下課,去吃飯,最好來一碗面條,來點兒辣椒再來點兒醋,那味道,呼呼流口水了,來到賣面條的地方,這個點兒來的人可真多啊,咱是好孩子,得排隊是不是,順便看一下标簽上有哪些面條,哇塞面條的種類可真多啊,比如有雪菜肉絲面條,蕃茄雞蛋面條,小雞蘑菇面條,聽,我前面的小姑娘要了一碗蕃茄雞蛋面條,緊接着一個男孩要了一碗小雞蘑菇面條,每個同學的選擇是不同的,也就是需求是各種各樣的,那麼這種情況在我們的程式設計世界中如何實作呢,這個時候,排隊的我想到了繼承,如下圖所示:
這個時候如果我想要加醋和加辣椒的面條?我要怎麼辦,可以通過繼承來實作擴充,但是這樣的設計有點兒笨笨的,于是一種新設計模式--裝飾模式就這樣橫空出世了,我們來看看裝飾模式的結構圖:
裝飾者模式呢,其實可以看做是一種在已有功能上動态添加新的功能的一種方式,在不用裝飾者模式的前提下,如果要在已有的功能上添加新功能,一般都是可以使用繼承的,但是,繼承的缺點呢,在上面的例子中也暴露的很明顯,同時,使用繼承的話,添加功能不是動态的,因為子類完全繼承了父類,而使用裝飾者模式的話,您可以在用戶端按照需求一個一個的包裝對象,通過包裝對象來添加新功能,這樣便實作了動态添加新功能,比如,我可以對 Component 通過 ConcreteDecoratorA
來包裝一個 State 狀态,或者是通過 ConcreteDecoratorB 來包裝一個新的行為(功能)Behavior ,以我們的面條例子為例,看看我們的程式是怎麼實作的呢?
先來看一下Eat類:
然後就是一個Noodle類:
下面再來看 DecoratorEat 類:
還有就是裝飾類 Tomato:
裝飾類雞蛋和豆皮的代碼跟上述裝飾類蕃茄雷同,再此不一一贅述,接下來,我們一起看看用戶端的代碼:
通過裝飾模式我們的小菜有着百搭的風格,而我也.......嘻嘻,再回到我們的裝飾模式中來,裝飾模式與繼承關系的目的都是要擴充對象的功能,但是Decorator可以提供比繼承更多的靈活性。 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行為的組合。設計之旅,未完待續......