国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript設(shè)計(jì)模式----職責(zé)鏈模式

boredream / 3434人閱讀

摘要:使用面向切面編程來快速的創(chuàng)建職責(zé)鏈的具體概念可以參考裝飾者模式實(shí)現(xiàn)職責(zé)鏈簡單又巧妙,但這種把函數(shù)疊在一起的方式,同時(shí)也疊加了函數(shù)的作用域,如果鏈條太長的話,也會(huì)對性能造成太大的影響。在開發(fā)中,職責(zé)鏈模式是最容易被忽視的模式之一。

聲明:這個(gè)系列為閱讀《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》 ----曾探@著一書的讀書筆記

1.職責(zé)鏈模式的定義

2.

2.1 簡單職責(zé)鏈模式

2.2職責(zé)鏈重構(gòu)上面的代碼

2.3靈活的拆分職責(zé)鏈節(jié)點(diǎn)

3.異步職責(zé)鏈

4.職責(zé)鏈模式的優(yōu)缺點(diǎn):

5.使用AOP(面向切面編程)來快速的創(chuàng)建職責(zé)鏈

總結(jié):

1.職責(zé)鏈模式的定義

使多個(gè)對象都有機(jī)會(huì)處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系,將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個(gè)對象處理它為止。

2. 2.1 簡單職責(zé)鏈模式

故事背景:用戶可以支付定金購買手機(jī),并且可以獲得優(yōu)惠券。沒有支付定金的就是普通用戶,進(jìn)入普通購買模式,沒有優(yōu)惠券,且?guī)齑娌蛔愕那闆r下不一定能夠買到手機(jī)。

/**
 *
 * @param orderType 訂單類型
 * @param pay   用戶是否已經(jīng)支付過定金 true or false
 * @param stock 表示手機(jī)的庫存量
 */
var order = function (orderType, pay, stock){
    if (orderType === 1) {
        if (pay === true) {
            console.log("500定金預(yù)購,得到100元優(yōu)惠券");
        }
        else {
            if (stock > 0) {
                console.log("普通購買,沒有優(yōu)惠券");
            }
            else {
                console.log("手機(jī)庫存不足");
            }
        }
    }
    else if (orderType === 2) {
        if (pay === true) {
            console.log("200定金預(yù)購,得到50元優(yōu)惠券");
        }
        else {
            if (stock > 0) {
                console.log("普通購買,沒有優(yōu)惠券");
            }
            else {
                console.log("手機(jī)庫存不足");
            }
        }
    }
    else if (orderType === 3) {
        if (stock > 0) {
            console.log("普通購買,沒有優(yōu)惠券");
        }
        else {
            console.log("手機(jī)庫存不足");
        }
    }
};
2.2職責(zé)鏈重構(gòu)上面的代碼

主要通過拆分功能語句,來使用職責(zé)鏈重構(gòu):

//500元訂單
var order500 = function (orderType, pay, stock){
    if (orderType === 1 && pay === true) {
        console.log("500定金預(yù)購,得到100元優(yōu)惠券");
    }
    else {
        order200(orderType, pay, stock);  //將請求傳遞給200
    }
};

//200元訂單
var order200 = function (orderType, pay, stock){
    if (orderType === 2 && pay === true) {
        console.log("200定金預(yù)購,得到50元優(yōu)惠券");
    }
    else {
        order(orderType, pay, stock);
    }
};

//普通購買訂單
var order = function (orderType, pay, stock){
    if (stock>0) {
        console.log("普通購買,沒有優(yōu)惠券");
    }
    else {
    console.log("手機(jī)庫存不足");
    }
};

//測試調(diào)用
order500(1,true,500);
order500(3,false,0);

總結(jié):
上面的代碼違反了開放-封閉的原則,請求在鏈條中傳遞的順序非常僵硬,傳遞請求的代碼被耦合在了業(yè)務(wù)函數(shù)中:

var order500 = function (orderType, pay, stock){
    if (orderType === 1 && pay === true) {
        console.log("500定金預(yù)購,得到100元優(yōu)惠券");
    }
    else {
        order200(orderType, pay, stock);  //將請求傳遞給200
    }
};
2.3靈活的拆分職責(zé)鏈節(jié)點(diǎn)

為什么要拆分職責(zé)鏈的節(jié)點(diǎn),因?yàn)槟程煨枰砑有碌穆氊?zé),就需要修改業(yè)務(wù)代碼(要修改的話,就需要先去了解他,熟悉它,花費(fèi)大量的時(shí)間)。這顯然不是每一個(gè)人所需要的。

//500元訂單
var order500 = function (orderType, pay, stock){
    if (orderType === 1 && pay === true) {
        console.log("500定金預(yù)購,得到100元優(yōu)惠券");
    }
    else {
        return "nextSuccessor";
    }
};

//200元訂單
var order200 = function (orderType, pay, stock){
    if (orderType === 2 && pay === true) {
        console.log("200定金預(yù)購,得到50元優(yōu)惠券");
    }
    else {
        return "nextSuccessor";
    }
};

//普通購買訂單
var order = function (orderType, pay, stock){
    if (stock>0) {
        console.log("普通購買,沒有優(yōu)惠券");
    }
    else {
        console.log("手機(jī)庫存不足");
    }
};

var Chain=function (fn){
    this.fn=fn;
    this.successor=null;
};

Chain.prototype.setNextSuccessor=function (successor){
    return this.successor=successor;
};

Chain.prototype.passRequest=function(){
    var ret= this.fn.apply(this,arguments);

    if(ret==="nextSuccessor"){
        return this.successor && this.successor.passRequest.apply(this.successor,arguments);
    }

    return ret;
};

var chainOrder500=new Chain(order500());
var chainOrder200=new Chain(order200());
var chainOrderNormal=new Chain(order());

chainOrder500.setNextSuccessor(chainOrder200);
chainOrder200.setNextSuccessor(chainOrderNormal);

chainOrder500.passRequest(1,true,500);
chainOrder500.passRequest(2,true,500);
chainOrder500.passRequest(1,false,0);

加入某天網(wǎng)站添加了300元定金購買的職責(zé),我只需要添加特定的節(jié)點(diǎn)就可以了:

//300元訂單
var order300=function (){

};

var chainOrder300=new Chain(order300());
chainOrder500.setNextSuccessor(chainOrder300);
chainOrder500.setNextSuccessor(chainOrder200);

這樣的話只需要編寫簡單的功能函數(shù),改變職責(zé)鏈中的相關(guān)節(jié)點(diǎn)的順序即可。

3.異步職責(zé)鏈

上面的職責(zé)鏈代碼中,每個(gè)節(jié)點(diǎn)函數(shù)同步返回一個(gè)特定的值nextSuccessor,來表示是否把請求傳遞給下一個(gè)節(jié)點(diǎn)。而現(xiàn)實(shí)開發(fā)中會(huì)遇到一些異步的問題,比如在一個(gè)節(jié)點(diǎn)中發(fā)起一個(gè)ajax異步請求,異步請求的結(jié)果才能決定是否繼續(xù)在職責(zé)鏈中passRequest

可以給Chain類添加一個(gè)原型方法Chain.prototype.next,表示手動(dòng)傳遞請求給職責(zé)鏈中的下一個(gè)節(jié)點(diǎn):

Chain.prototype.next=function(){
    return this.successor && this.successor.passRequest.apply(this.successor,arguments);
};



//異步職責(zé)鏈的例子
var fn1=new Chain(function (){
    console.log(1);
    return "nextSuccessor";
});

var fn2=new Chain(function (){
    console.log(2);
    var self=this;
    setTimeout(function (){
        self.next();
    },1000);

});

var fn3=new Chain(function (){
    console.log(3);

});

fn1.setNextSuccessor(fn2).setNextSuccessor(fn3);
fn1.passRequest();
4.職責(zé)鏈模式的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):

職責(zé)鏈最大的優(yōu)點(diǎn)就是解耦了請求發(fā)送者和N個(gè)接收者之間的復(fù)雜關(guān)系。

職責(zé)鏈可以手動(dòng)指定起始節(jié)點(diǎn),請求并不是非得從鏈中的第一個(gè)節(jié)點(diǎn)開始傳遞。

缺點(diǎn):

不能保證某個(gè)請求一定會(huì)被鏈中的節(jié)點(diǎn)處理,這種情況可以在鏈尾增加一個(gè)保底的接受者節(jié)點(diǎn)來處理這種即將離開鏈尾的請求。

使程序中多了很多節(jié)點(diǎn)對象,可能再一次請求的過程中,大部分的節(jié)點(diǎn)并沒有起到實(shí)質(zhì)性的作用。他們的作用僅僅是讓請求傳遞下去,從性能當(dāng)面考慮,要避免過長的職責(zé)鏈到來的性能損耗。

5.使用AOP(面向切面編程)來快速的創(chuàng)建職責(zé)鏈

AOP的具體概念可以參考裝飾者模式

Function.prototype.after=function(fn){
    var self=this;
    return function(){
        var ret=self.apply(this,arguments);
        if(ret==="nextSuccessor"){
            return fn.apply(this,arguments);
        }

        return ret;
    }
};


var order=order500yuan.after(order200yuan).after(orderNormal);

order(1,true,500);
order(1,false,500);

AOP實(shí)現(xiàn)職責(zé)鏈簡單又巧妙,但這種把函數(shù)疊在一起的方式,同時(shí)也疊加了函數(shù)的作用域,如果鏈條太長的話,也會(huì)對性能造成太大的影響。

總結(jié):

職責(zé)鏈模式最大的優(yōu)點(diǎn):請求發(fā)送者只需要知道鏈中的第一個(gè)節(jié)點(diǎn),從而弱化了發(fā)送者和一組接收者之前的強(qiáng)聯(lián)系。

在JavaScript開發(fā)中,職責(zé)鏈模式是最容易被忽視的模式之一。但是只要運(yùn)用得當(dāng),職責(zé)鏈模式可以很好的幫助我們管理代碼,降低發(fā)起請求的對象和處理請求的對象之間的耦合性。且職責(zé)鏈中節(jié)點(diǎn)的數(shù)量和數(shù)序是可以自由變化的。可以在運(yùn)行時(shí)決定鏈中包含哪些節(jié)點(diǎn)。

無論是作用域鏈,原型鏈,還是DOM節(jié)點(diǎn)中的事件冒泡,我們都能從中找到職責(zé)鏈模式的影子。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/90839.html

相關(guān)文章

  • 前端開發(fā)中常用的javascript設(shè)計(jì)模式

    摘要:代理模式,迭代器模式,單例模式,裝飾者模式最少知識(shí)原則一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少地與其他實(shí)體發(fā)生相互作用。迭代器模式可以將迭代的過程從業(yè)務(wù)邏輯中分離出來,在使用迭代器模式之后,即不用關(guān)心對象內(nèi)部構(gòu)造也可以按順序訪問其中的每個(gè)元素。 接手項(xiàng)目越來越復(fù)雜的時(shí)候,有時(shí)寫完一段代碼,總感覺代碼還有優(yōu)化的空間,卻不知道從何處去下手。設(shè)計(jì)模式主要目的是提升代碼可擴(kuò)展性以及可閱讀性。 本文主要以例子的...

    趙春朋 評(píng)論0 收藏0
  • javascript設(shè)計(jì)模式--裝飾者模式

    摘要:裝飾者模式定義裝飾者模式能夠在不改變對象自身的基礎(chǔ)上,在程序運(yùn)行期間給對像動(dòng)態(tài)的添加職責(zé)。與繼承相比,裝飾者是一種更輕便靈活的做法。 裝飾者模式 定義 : 裝飾者(decorator)模式能夠在不改變對象自身的基礎(chǔ)上,在程序運(yùn)行期間給對像動(dòng)態(tài)的添加職責(zé)。與繼承相比,裝飾者是一種更輕便靈活的做法。 在不改變對象自身的基礎(chǔ)上,在程序運(yùn)行期間給對象動(dòng)態(tài)地添加一些額外職責(zé) 特點(diǎn) : 可以動(dòng)態(tài)的...

    haoguo 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》讀書筆記

    摘要:訂閱模式的一個(gè)典型的應(yīng)用就是后面會(huì)寫一篇相關(guān)的讀書筆記。享元模式享元模式的核心思想是對象復(fù)用,減少對象數(shù)量,減少內(nèi)存開銷。適配器模式對目標(biāo)函數(shù)進(jìn)行數(shù)據(jù)參數(shù)轉(zhuǎn)化,使其符合目標(biāo)函數(shù)所需要的格式。 設(shè)計(jì)模式 單例模式 JS的單例模式有別于傳統(tǒng)面向?qū)ο笳Z言的單例模式,js作為一門無類的語言。使用全局變量的模式來實(shí)現(xiàn)單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個(gè)實(shí)例...

    Panda 評(píng)論0 收藏0
  • JavaScript常用的設(shè)計(jì)模式

    摘要:前言設(shè)計(jì)模式幾十種,閱讀了設(shè)計(jì)模式與開發(fā)實(shí)踐這本書后,個(gè)人感覺就是圍繞對象來設(shè)計(jì)的,發(fā)現(xiàn)日常寫代碼能用上的并不多,下面是常用的幾種設(shè)計(jì)模式。前端服務(wù)端可以參考我的另一個(gè)倉庫地址,一個(gè)簡單的實(shí)時(shí)聊天參考來自設(shè)計(jì)模式與開發(fā)實(shí)踐讀書筆記 前言 設(shè)計(jì)模式幾十種,閱讀了《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》這本書后,個(gè)人感覺js就是圍繞對象來設(shè)計(jì)的,發(fā)現(xiàn)日常寫代碼能用上的并不多,下面是常用的...

    mengbo 評(píng)論0 收藏0
  • 傳遞請求之職責(zé)模式

    摘要:想一想,這個(gè)和我們的迭代器模式有著異曲同工的妙處,迭代器模式同樣也是遍歷選出最優(yōu)解,但是相比而言,職責(zé)鏈模式的直觀性個(gè)書寫的幸福感是遠(yuǎn)遠(yuǎn)超過迭代器模式的。 職責(zé)鏈模式其實(shí)很好理解,由于一個(gè)鏈字出賣了它的靈魂。我們可以從這個(gè)字得到很大的提示。首先這個(gè)模式一定有傳遞性,而且,節(jié)點(diǎn)是可以重復(fù)拼接的,并且每個(gè)節(jié)點(diǎn)都具有一定的過濾功能,一定的職責(zé)。 是不是想起了組合模式里的一些內(nèi)容呢? 是的,他...

    wslongchen 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

boredream

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<