結(jié)構(gòu)型模式類型:裝飾者模式--AOP裝飾

AOP在職責模式中也有使用,初學設(shè)計模式過程中权薯,AOP是性價比最高的姑躲,在實際開發(fā)中的作用也很重要,學習AOP你可以在不改動原來大量代碼功能模塊的前提下對功能進行改造盟蚣,添加插件黍析,添加功能。比如提交ajax請求提交前屎开,添加驗證功能阐枣,或者修改params。同時也不會修改原有代碼奄抽。

如何理解AOP(切面編程)

AOP中文名叫面向切面編程蔼两。打一個通俗易懂的比喻,現(xiàn)在我們手上有一摞撲克牌如孝,發(fā)牌的過程可以看做是JS的執(zhí)行過程宪哩,一張撲克牌就是一個功能,可能是一個簡單的console.log第晰,也可能是復(fù)雜的http請求锁孟,這張卡牌是??7,如果我想在發(fā)牌過程中連續(xù)拿到??6茁瘦、??7品抽、??8。再不打亂整副牌的前提下甜熔,只需要在??7前加入??6圆恤,??7后面插入??8。當然你可以重寫??7腔稀,直接在牌面上加上新的程序盆昙,不過改變了原有的程序代碼羽历,并不優(yōu)雅;

原來的??7
 var ??7 = function(){
    console.log(??7);
}
作弊:改寫??7
var ??7= function(){
    console.log(??6);
    console.log(??7);
    console.log(??8);
}
理想的:添加新的卡牌(函數(shù))
var ??6 = function(){
    console.log(??6);
}
var ??8 = function(){
    console.log(??8);
}
function(){
    ??6()
    ??7()
    ??8()
}

JS中AOP的核心內(nèi)容

Function.prototype.after = function(fn){
    var _this = this;
    return function(){
        var res = _this.apply(this,arguments);
        fn.apply(this,arguments);
        return res;
    }
}
Function.prototype.before = function(fn){
    var _this = this;
    return function(){
        fn.apply(this,arguments);  
        return    _this.apply(this,arguments);
    }
}

通過重寫原型鏈淡喜,我們在調(diào)用函數(shù)的時候秕磷,就可以使用原型鏈上的before 和after方法。
下面我們通過一個代碼片段看一看炼团,代碼是怎么運行的澎嚣,可以將代碼在瀏覽器中運行一下,跟著debugger;瘟芝,多試幾次易桃,更容易理解。

測試代碼講解

Function.prototype.before = function(fn){
    var _self = this;
    console.log(this)
    debugger;
    return function () {

        //返回值判斷,如果為false那么不執(zhí)行,表示業(yè)務(wù)邏輯執(zhí)行失敗
        if(fn.apply(this,arguments) === false){
            return false
        }
        console.log(this)
        debugger;
        return _self.apply(_self,arguments)
    }
}

Function.prototype.after = function(fn){
    var _self = this;
    console.log(this);
    debugger;
     return function () {
        var result = _self.apply(_self,arguments)
        console.log(this)
        debugger;
        fn.apply(this,arguments)
        return result
    }
}


function test(val){
    debugger;
    console.log(val)
}

// 編寫初始處理
function fInter(val){
    console.log(val-1)
}
//編寫后續(xù)處理
function fOuter(val){
    console.log(val+1)
}
console.log('before')
test.before(fInter)  //返回一個為執(zhí)行函數(shù)
console.log('before()')
test.before(fInter)(8);//傳入?yún)?shù)并將上面返回的函數(shù)執(zhí)行
console.log('after()')
test.after(fOuter)(8)//傳入?yún)?shù)并執(zhí)行返回的函數(shù)
test.before(fInter).after(fOuter)(8)//分為兩步锌俱,test.before(flnter)首先返回一個函數(shù)晤郑,
                //這個函數(shù)里是需求的順序,然后將這個函數(shù)的作為作用域傳到
                //.after(fOuter)中去嚼鹉,作為一個單獨的函數(shù)贩汉,及_self.apply(_self,arguments)進行執(zhí)行。

Function.prototype.after中的result 作用

Function.prototype.after = function(fn){
    var _self = this;
    console.log(this);
    debugger;
     return function () {
        var result =  _self.apply(_self,arguments)
        console.log(this)
        debugger;
         fn.apply(this,arguments)
        return result 
    }
}

test.before(fInter).after(fOuter)(7)

result是為了記錄之前添加好的函數(shù)的集合

打印結(jié)果:
//test(val){
    console.log(val)
}
//function(){ 返回加工后的函數(shù):可以稱為addFnbefore()
    fnBefore()
    text()
}
//funtion(){  返回最終加工后的函數(shù)也就是接下來要運行的函數(shù):endFn()
    addFnbefore()
    fnAfter()
}
最后執(zhí)行endFn() 
//6
//7
//8

如何打斷

例如我們在提交請求加入了一個fnBefore用來判斷用戶輸入?yún)?shù)是否有效锚赤,就需要在錯誤的時候打斷提交操作

Function.prototype.before = function(fn){
    var _self = this
    return function () {
        //返回值判斷,如果為false那么不執(zhí)行,表示業(yè)務(wù)邏輯執(zhí)行失敗
        if(fn.apply(this,arguments) === false){
            return false
        }
        return _self.apply(_self,arguments)
    }
}

Function.prototype.after = function(fn){
    var _self = this;
     return function () {
        var result = _self.apply(_self,arguments)
        //after有返回值判斷,如果為false那么不執(zhí)行,表示業(yè)務(wù)邏輯執(zhí)行失敗
        if(result === false){
            return false;
        }
        fn.apply(this,arguments)
        return result
    }
}

如果fn匹舞,為false函數(shù)將停止執(zhí)行。

如何不修改Function的原型鏈前提下實現(xiàn)AOP

持續(xù)更新

學學AOP之裝飾者模式
js 面向切面編程
AOP PPT講解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末线脚,一起剝皮案震驚了整個濱河市赐稽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌浑侥,老刑警劉巖姊舵,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異寓落,居然都是意外死亡括丁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門伶选,熙熙樓的掌柜王于貴愁眉苦臉地迎上來史飞,“玉大人,你說我怎么就攤上這事仰税」棺剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵陨簇,是天一觀的道長吐绵。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么己单? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任唉窃,我火速辦了婚禮,結(jié)果婚禮上荷鼠,老公的妹妹穿的比我還像新娘句携。我一直安慰自己榔幸,他們只是感情好允乐,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著削咆,像睡著了一般牍疏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拨齐,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天鳞陨,我揣著相機與錄音,去河邊找鬼瞻惋。 笑死厦滤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的歼狼。 我是一名探鬼主播掏导,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼羽峰!你這毒婦竟也來了趟咆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤梅屉,失蹤者是張志新(化名)和其女友劉穎值纱,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坯汤,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡虐唠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了惰聂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疆偿。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖庶近,靈堂內(nèi)的尸體忽然破棺而出翁脆,到底是詐尸還是另有隱情,我是刑警寧澤鼻种,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布反番,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏罢缸。R本人自食惡果不足惜篙贸,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枫疆。 院中可真熱鬧爵川,春花似錦、人聲如沸息楔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽值依。三九已至圃泡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愿险,已是汗流浹背颇蜡。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留辆亏,地道東北人风秤。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像扮叨,于是被迫代替她去往敵國和親缤弦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容