若把物件視為洋蔥,物件的責任像洋蔥皮般一層層分開,你想要給物件幾個責任就拿幾層皮包起來(decorate),物件無論怎麼看都是一顆洋蔥。
裝飾者模式動態地將責任加諸於物件上。想要擴充功能,裝飾者提供有別於繼承的另一個選擇。
繼承屬於擴充形式之一,但不見得是達到彈性設計的最佳方法。
本範式巧妙應用了繼承,目的在求裝飾者與被裝飾者達到「一樣的型態」,非用繼承取得相同的行為,行為仍舊是靠合成(composition)而來。也就是當裝飾者(decorator)與元件(component)合成時,就是加入新的行為。
裝飾者繼承了元件以達到型態相同,也合成了元件以獲的行為。
裝飾者可以在所委派被裝飾者的行為之前或/與之後加上自己的行為。
當有新的裝飾者出現時,不用更動原有程式,只消加入該裝飾者物件即可。
裝飾者物件通常都用工廠範式(Factory Method Pattern or Abstract Factory Pattern)或建立者範式(Builder Pattern)來創建。
被裝飾者與裝飾者間並不知道彼此的存在。
使用此範式會導至出現許多小類別,若過度使用會讓軟體變複雜。
適合用IoC container定義物件的責任。
OCP(Open Closed Principle)
類別應對擴充採開放態度;應對修改採封閉態度。
勿盲目追求OCP,應視需求定義,在最可能發生需求改變的部份導入OCP。
需要擴充一個類別的功能,或給一個類別增加附加責任。
需要動態地給一個物件增加功能,這些功能可以再動態地撤銷。
需要增加由一些基本功能的排列組合而產生的非常大量的功能,若用繼承就不太適合時。
意思是client可以宣告concrete decorator 類別的變數,從而可以呼叫 concrete decorator類別中才有的方法。