冬天已經來臨,北方的小夥伴們是否是感受天氣一天比一天冷了呢?從秋天過渡到冬天,冷了就穿一件毛衣,若是穿上毛衣還以爲冷可能會添一件羽絨服,若是下雪天可能就須要穿上雨衣或者帶上雨傘了。在咱們生活中這些衣服以拓展的方式給了你溫暖,可是它們並非你的一部分,若是到了春天那麼這些衣服可能會一一的脫掉了。學習
在軟件開發過程當中,有事想用一些現存的類或者組件,這些類或者組件可能只是完成了一些核心功能。但在不改變其結構的狀況下,能夠動態的拓展其功能。全部這些均可以用裝飾模式來實現。this
什麼裝飾模式
裝飾模式:指的是在沒必要改變原類文件和使用繼承的狀況下,動態地擴展一個對象的功能。它是經過建立一個包裝對象,也就是裝飾來包裹真實的對象。 —— 節選自百度百科編碼
裝飾模式有兩種方式能夠實現給一個類或者一個對象添加行爲,第一種是使用繼承,使用繼承是給現有類添加功能的一種有效途徑,經過繼承一個現有類能夠使得子類在擁有自身方法的同時還擁有父類的方法。可是這種方法是靜態的,用戶不能控制增長行爲的方式和時機。第一種則是使用關聯的方法,即將一個類的對象嵌入到另外一個對象中,由另外一個對象來決定是否調用嵌入對象的行爲以便擴展本身的行爲。spa
裝飾模式優缺點
裝飾模式以對客戶透明的方式動態地給一個對象附加上更多的責任,換言之,客戶端並不會以爲對象在裝飾前和裝飾後有什麼不一樣。裝飾模式能夠在不須要建立更多子類的狀況下,將對象的功能加以擴展。設計
優勢
缺點
示例
裝飾模式的主要角色以下:調試
類圖以下所示:code
代碼示例:component
// 抽象構件 abstract class Component { public abstract operate() : void; } // 具體構件 class ConcreteComponent extends Component { public operate() : void { console.log('do something'); } } // 裝飾角色 abstract class Decorator extends Component { private component : Component = null; constructor(component : Component ) { super(); this.component = component; } public operate() : void { this.component.operate(); } } // 具體裝飾者 class ConcreteDecoratorA extends Decorator { constructor(component : Component) { super(component); } // 定義本身的修飾方法 private methodA() : void { console.log('methodA修飾'); } // 重寫父類方法 public operate() : void { this.methodA(); super.operate(); } } class ConcreteDecoratorB extends Decorator { constructor(component : Component) { super(component); } // 定義本身的修飾方法 private methodB() : void { console.log('methodB修飾'); } // 重寫父類方法 public operate() : void { this.methodB(); super.operate(); } } function main() { let component : Component = new ConcreteComponent(); // 第一次裝飾 component = new ConcreteDecoratorA(component); // 第二次裝飾 component = new ConcreteDecoratorB(component); // 裝飾後運行 component.operate(); } main();
總結
裝飾模式來實現擴展比繼承更加靈活,它以對客戶透明的方式動態地給一個對象附加更多的責任。裝飾模式能夠在不須要創造更多子類的狀況下,將對象的功能加以擴展。對象
繼承是一種耦合度較大的靜態關係,沒法在程序運行時動態擴展。在軟件開發階段,關聯關係雖然不會比繼承關係減小編碼量,可是到了軟件維護階段,因爲關聯關係使系統具備較好的鬆耦合性,所以使得系統更加容易維護。blog