摘要:聲明這個(gè)系列為閱讀設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐曾探著一書(shū)的讀書(shū)筆記裝飾者模式的定義裝飾者模式能夠在不改變對(duì)象自身的基礎(chǔ)上,在程序運(yùn)行期間給對(duì)像動(dòng)態(tài)的添加職責(zé)。與繼承相比,裝飾者是一種更輕便靈活的做法。裝飾者模式的作用就是為對(duì)象動(dòng)態(tài)的加入某些行為。
聲明:這個(gè)系列為閱讀《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》 ----曾探@著一書(shū)的讀書(shū)筆記
裝飾者模式的定義:裝飾者(decorator)模式能夠在不改變對(duì)象自身的基礎(chǔ)上,在程序運(yùn)行期間給對(duì)像動(dòng)態(tài)的添加職責(zé)。與繼承相比,裝飾者是一種更輕便靈活的做法。
裝飾者模式的特點(diǎn):可以動(dòng)態(tài)的給某個(gè)對(duì)象添加額外的職責(zé),而不會(huì)影響從這個(gè)類(lèi)中派生的其它對(duì)象;
繼承的一些缺點(diǎn):繼承會(huì)導(dǎo)致超類(lèi)和子類(lèi)之間存在強(qiáng)耦合性,當(dāng)超類(lèi)改變時(shí),子類(lèi)也會(huì)隨之改變;
超類(lèi)的內(nèi)部細(xì)節(jié)對(duì)于子類(lèi)是可見(jiàn)的,繼承常常被認(rèn)為破壞了封裝性;
傳統(tǒng)面向?qū)ο蟮难b飾者和JavaScript裝飾者對(duì)比: 1.模擬傳統(tǒng)面向?qū)ο笳Z(yǔ)言的裝飾者模式//模擬傳統(tǒng)語(yǔ)言的裝飾者 //原始的飛機(jī)類(lèi) var Plan = function () { }; Plan.prototype.fire = function () { console.log("發(fā)射普通子彈"); }; //裝飾類(lèi) var MissileDecorator = function (plan) { this.plan = plan; } MissileDecorator.prototype.fire = function () { this.plan.fire(); console.log("發(fā)射導(dǎo)彈!"); }; var plan = new Plan(); plan = new MissileDecorator(plan); plan.fire();2.JavaScript中的裝飾者模式
裝飾者模式將一個(gè)對(duì)象嵌入到另一個(gè)對(duì)象之中,實(shí)際上相當(dāng)于這個(gè)對(duì)象被另一個(gè)對(duì)像包裝起來(lái),形成一條包裝鏈。請(qǐng)求隨著這條包裝鏈依次傳遞到所有的對(duì)象,每個(gè)對(duì)象都有處理這條請(qǐng)求的機(jī)會(huì)。
var Plan1 = { fire: function () { console.log("發(fā)射普通的子彈"); } }; var missileDecorator= function () { console.log("發(fā)射導(dǎo)彈!"); }; var fire = Plan1.fire; Plan1.fire=function () { fire(); missileDecorator(); }; Plan1.fire();裝飾函數(shù)
在JavaScript中可以很方便的給某個(gè)對(duì)象擴(kuò)展屬性和方法,但卻很難在不改動(dòng)某個(gè)函數(shù)源代碼的情況下,給該函數(shù)添加一些額外的功能。也就是在代碼運(yùn)行期間,我們很難切入某個(gè)函數(shù)的執(zhí)行環(huán)境。
1.使用裝飾者模式例子//對(duì)window.onload的處理 window.onload=function () { console.log("test"); }; var _onload= window.onload || function () {}; window.onload=function () { _onload(); console.log("自己的處理函數(shù)"); };2.使用AOP(面向切面編程)裝飾函數(shù)
主要是以為在JavaScript中會(huì)存在隨著函數(shù)的調(diào)用,this的指向發(fā)生變化,導(dǎo)致執(zhí)行結(jié)果發(fā)生變化。
在需要執(zhí)行的函數(shù)之前執(zhí)行某個(gè)新添加的功能函數(shù)
//是新添加的函數(shù)在舊函數(shù)之前執(zhí)行 Function.prototype.before=function (beforefn) { var _this= this; //保存舊函數(shù)的引用 return function () { //返回包含舊函數(shù)和新函數(shù)的“代理”函數(shù) beforefn.apply(this,arguments); //執(zhí)行新函數(shù),且保證this不被劫持,新函數(shù)接受的參數(shù) // 也會(huì)被原封不動(dòng)的傳入舊函數(shù),新函數(shù)在舊函數(shù)之前執(zhí)行 return _this.apply(this,arguments); }; };
在需要執(zhí)行的函數(shù)之后執(zhí)行某個(gè)新添加的功能函數(shù)
//新添加的函數(shù)在舊函數(shù)之后執(zhí)行 Function.prototype.after=function (afterfn) { var _this=this; return function () { var ret=_this.apply(this,arguments); afterfn.apply(this,arguments); return ret; }; };
var before=function (fn, before) { return function () { before.apply(this,arguments); return fn.apply(this,arguments); }; }; function func1(){console.log("1")} function func2() {console.log("2")} var a=before(func1,func2); // a=before(a,func1); a();裝飾者模式用法示例: 1.ajax動(dòng)態(tài)添加參數(shù)
使用裝飾者模式動(dòng)態(tài)的改變ajax函數(shù),傳輸?shù)膮?shù)
//是新添加的函數(shù)在舊函數(shù)之前執(zhí)行 Function.prototype.before=function (beforefn) { var _this= this; //保存舊函數(shù)的引用 return function () { //返回包含舊函數(shù)和新函數(shù)的“代理”函數(shù) beforefn.apply(this,arguments); //執(zhí)行新函數(shù),且保證this不被劫持,新函數(shù)接受的參數(shù) // 也會(huì)被原封不動(dòng)的傳入舊函數(shù),新函數(shù)在舊函數(shù)之前執(zhí)行 return _this.apply(this,arguments); }; }; var func = function (param) { console.log(param); }; func = func.before(function (param) { param.b = "b"; }); func({b:"222"}); //給ajax請(qǐng)求動(dòng)態(tài)添加參數(shù)的例子 var ajax=function (type,url,param) { console.log(param); }; var getToken=function () { return "Token"; }; ajax=ajax.before(function (type, url, param) { param.token=getToken(); }); ajax("get","http://www.jn.com",{name:"zhiqiang"});2.表單驗(yàn)證并且提交
裝飾者模式分離表單驗(yàn)證和提交的函數(shù)
Function.prototype.before=function (beforefn) { var _this= this; //保存舊函數(shù)的引用 return function () { //返回包含舊函數(shù)和新函數(shù)的“代理”函數(shù) beforefn.apply(this,arguments); //執(zhí)行新函數(shù),且保證this不被劫持,新函數(shù)接受的參數(shù) // 也會(huì)被原封不動(dòng)的傳入舊函數(shù),新函數(shù)在舊函數(shù)之前執(zhí)行 return _this.apply(this,arguments); }; }; var validata=function () { if(username.value===""){ alert("用戶名不能為空!") return false; } if(password.value===""){ alert("密碼不能為空!") return false; } } var formSubmit=function () { var param={ username=username.value; password=password.value; } ajax("post","http://www.mn.com",param); } formSubmit= formSubmit.before(validata); submitBtn.onclick=function () { formSubmit(); }總結(jié):
裝飾者模式和代理模式的區(qū)別:
代理模式的目的是,當(dāng)直接訪問(wèn)本體不方便或者不符合需要時(shí),為這個(gè)本體提供一個(gè)代替者。本體定義了關(guān)鍵功能,而代理提供了或者拒絕對(duì)他的訪問(wèn),或者是在訪問(wèn)本體之前做一些額外的事情。
裝飾者模式的作用就是為對(duì)象動(dòng)態(tài)的加入某些行為。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87781.html
摘要:下裝飾者的實(shí)現(xiàn)了解了裝飾者模式和的概念之后,我們寫(xiě)一段能夠兼容的代碼來(lái)實(shí)現(xiàn)裝飾者模式原函數(shù)拍照片定義函數(shù)裝飾函數(shù)加濾鏡用裝飾函數(shù)裝飾原函數(shù)這樣我們就實(shí)現(xiàn)了抽離拍照與濾鏡邏輯,如果以后需要自動(dòng)上傳功能,也可以通過(guò)函數(shù)來(lái)添加。 showImg(https://segmentfault.com/img/bVbueyz?w=852&h=356); 什么是裝飾者模式 當(dāng)我們拍了一張照片準(zhǔn)備發(fā)朋友...
摘要:設(shè)計(jì)模式裝飾者模式何為裝飾者,意思就是,在不影響對(duì)象主功能的情況下,再添加一些額外的功能,使對(duì)象具備更多的功能。與繼承相比,裝飾者是一種更靈活輕便的做法。 javascript設(shè)計(jì)模式 --- 裝飾者模式 何為裝飾者,意思就是,在不影響對(duì)象主功能的情況下,再添加一些額外的功能,使對(duì)象具備更多的功能。與繼承相比,裝飾者是一種更靈活輕便的做法。下面我們看看javascript里裝飾者模式 ...
摘要:裝飾者模式定義裝飾者模式能夠在不改變對(duì)象自身的基礎(chǔ)上,在程序運(yùn)行期間給對(duì)像動(dòng)態(tài)的添加職責(zé)。與繼承相比,裝飾者是一種更輕便靈活的做法。 裝飾者模式 定義 : 裝飾者(decorator)模式能夠在不改變對(duì)象自身的基礎(chǔ)上,在程序運(yùn)行期間給對(duì)像動(dòng)態(tài)的添加職責(zé)。與繼承相比,裝飾者是一種更輕便靈活的做法。 在不改變對(duì)象自身的基礎(chǔ)上,在程序運(yùn)行期間給對(duì)象動(dòng)態(tài)地添加一些額外職責(zé) 特點(diǎn) : 可以動(dòng)態(tài)的...
摘要:裝飾者模式裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對(duì)象,用于通過(guò)重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為以達(dá)到特定的目的。簡(jiǎn)單的理解給對(duì)象動(dòng)態(tài)添加職責(zé)的方式稱為裝飾著模式。 裝飾者模式 裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對(duì)象,用于通過(guò)重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為...
摘要:?jiǎn)误w模式有以下優(yōu)點(diǎn)用來(lái)劃分命名空間,減少全局變量數(shù)量。通常我們使用操作符創(chuàng)建單體模式的三種選擇,讓構(gòu)造函數(shù)總返回最初的對(duì)象使用全局對(duì)象來(lái)存儲(chǔ)該實(shí)例不推薦,容易全局污染。實(shí)現(xiàn)該工廠模式并不困難,主要是要找到能夠穿件所需類(lèi)型對(duì)象的構(gòu)造函數(shù)。 介紹 最近開(kāi)始給自己每周訂個(gè)學(xué)習(xí)任務(wù),學(xué)習(xí)結(jié)果反饋為一篇文章的輸出,做好學(xué)習(xí)記錄。 這一周(02.25-03.03)我定的目標(biāo)是《JavaScri...
閱讀 2216·2021-11-22 11:56
閱讀 2659·2021-10-08 10:05
閱讀 7843·2021-09-22 15:53
閱讀 1928·2021-09-22 15:29
閱讀 2249·2021-09-08 09:35
閱讀 3372·2021-09-07 10:12
閱讀 1393·2019-08-30 13:11
閱讀 1994·2019-08-28 17:54