概念:可以動(dòng)態(tài)地給某個(gè)對(duì)象添加一些額外的職責(zé),而不會(huì)影響從這個(gè)類中派生的其他對(duì)象。
出現(xiàn)原因:在裝飾者出現(xiàn)之前,我們都是用繼承給對(duì)象添加功能,但是繼承也不是萬(wàn)能的,會(huì)出現(xiàn)一些瑕疵,裝飾者模式的出現(xiàn)就恰恰彌補(bǔ)了這些瑕疵。
- 繼承的超類和子類之間存在強(qiáng)耦合性,當(dāng)超類改變時(shí),子類也會(huì)隨之改變;
- 繼承的超類的內(nèi)部細(xì)節(jié)對(duì)子類是可見的,會(huì)被認(rèn)為破壞了封裝性。
舉栗子(假設(shè)我們?cè)诰帉懸粋€(gè)飛機(jī)大戰(zhàn)的游戲,隨著經(jīng)驗(yàn)值的增加,我們操作的飛機(jī)對(duì)象可以升級(jí)成更厲害的飛機(jī),一開始這些飛機(jī)只能發(fā)射普通的子彈,升到第二級(jí)時(shí)可以發(fā)射導(dǎo)彈,升到第三級(jí)時(shí)可以發(fā)射原子彈。):
var plane = {
fire: function(){
console.log( '發(fā)射普通子彈' );
}
}
var missileDecorator = function(){
console.log( '發(fā)射導(dǎo)彈' );
}
var atomDecorator = function(){
console.log( '發(fā)射原子彈' );
}
var fire1 = plane.fire;
plane.fire = function(){
fire1();
missileDecorator();
}
var fire2 = plane.fire;
plane.fire = function(){
fire2();
atomDecorator();
}
plane.fire();
// 分別輸出: 發(fā)射普通子彈、發(fā)射導(dǎo)彈、發(fā)射原子彈
裝飾者模式和代理模式看起來(lái)相像,但它們有明顯的不同:
代理模式的目的是,當(dāng)直接訪問(wèn)本體不方便或者不符合需要時(shí),為這個(gè)本體提供一個(gè)替代者。本體定義了關(guān)鍵功能,而代理提供或拒絕對(duì)它的訪問(wèn),或者在訪問(wèn)本體之前做一些額外的事情。
裝飾者模式的作用就是為對(duì)象動(dòng)態(tài)加入行為,裝飾者模式用于一開始不能確定對(duì)象的全部功能時(shí)。。