首頁  >  文章  >  web前端  >  js設計模式:什麼是職責鏈模式? js職責鏈模式的介紹

js設計模式:什麼是職責鏈模式? js職責鏈模式的介紹

不言
不言原創
2018-08-17 16:43:571457瀏覽

這篇文章帶給大家的內容是關於js設計模式:什麼是職責鏈模式? js職責鏈模式的介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

什麼是職責鏈模式?

#重要:4 顆星,在專案中能對if-else 語句進行最佳化

定義:避免請求發送者與接收者耦合在一起,讓多個物件都有可能接收請求,將這些物件連接成一條鏈,並且沿著這條鏈傳遞請求,直到有物件處理它為止。

主要解決:職責鏈上的處理者負責處理請求,客戶只需要將請求發送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的發送者和請求的處理者解耦了。

何時使用:在處理訊息的時候以過濾很多道。

如何解決:攔截的類別都實作統一介面。

js職責鏈模式應用實例: 1、紅樓夢中的"擊鼓傳花"。 2、JS 中的事件冒泡。 3.JAVA WEB 中 Apache Tomcat 對 Encoding 的處理,Struts2 的攔截器,jsp servlet 的 Filter。

js職責鏈模式優點: 1、降低耦合度。它將請求的發送者和接收者解耦。 2.簡化了對象。使得物件不需要知道鏈的結構。 3、增強給對象指派職責的彈性。透過改變鏈內的成員或調動它們的次序,允許動態地新增或刪除責任。 4.增加新的請求處理類別很方便。

js職責鏈模式缺點: 1、無法保證請求一定會被接收。 2、系統效能將受到一定影響,而且在進行程式碼調試時不太方便,可能會造成循環呼叫。 3.可能不容易觀察運行時的特徵,有礙於調試。

js職責鏈模式使用場景: 1、有多個物件可以處理同一個請求,具體哪個物件處理該請求由運行時刻自動決定。 2、在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。 3.可動態指定一組物件處理請求。

js職責鏈模式場景

場景:某電商針對已付過定金的用戶有優惠政策,在正式購買後,已經支付過500 元定金的用戶會收到100元的優惠券,200 元訂金的用戶可以收到50 元優惠券,沒有支付過定金的用戶只能正常購買。

// orderType: 表示订单类型,1:500 元定金用户;2:200 元定金用户;3:普通购买用户
// pay:表示用户是否已经支付定金,true: 已支付;false:未支付
// stock: 表示当前用于普通购买的手机库存数量,已支付过定金的用户不受此限制

const order = function( orderType, pay, stock ) {
  if ( orderType === 1 ) {
    if ( pay === true ) {
      console.log('500 元定金预购,得到 100 元优惠券')
    } else {
      if (stock > 0) {
        console.log('普通购买,无优惠券')
      } else {
        console.log('库存不够,无法购买')
      }
    }
  } else if ( orderType === 2 ) {
    if ( pay === true ) {
      console.log('200 元定金预购,得到 50 元优惠券')
    } else {
      if (stock > 0) {
        console.log('普通购买,无优惠券')
      } else {
        console.log('库存不够,无法购买')
      }
    }
  } else if ( orderType === 3 ) {
    if (stock > 0) {
        console.log('普通购买,无优惠券')
    } else {
      console.log('库存不够,无法购买')
    }
  }
}

order( 3, true, 500 ) // 普通购买,无优惠券

下面用職責鏈模式改進程式碼

const order500 = function(orderType, pay, stock) {
  if ( orderType === 1 && pay === true ) {
    console.log('500 元定金预购,得到 100 元优惠券')
  } else {
    order200(orderType, pay, stock)
  }
}

const order200 = function(orderType, pay, stock) {
  if ( orderType === 2 && pay === true ) {
    console.log('200 元定金预购,得到 50 元优惠券')
  } else {
    orderCommon(orderType, pay, stock)
  }
}

const orderCommon = function(orderType, pay, stock) {
  if (orderType === 3 && stock > 0) {
    console.log('普通购买,无优惠券')
  } else {
    console.log('库存不够,无法购买')
  }
}

order500( 3, true, 500 ) // 普通购买,无优惠券

改造後可以發現程式碼相對清晰了,但是鏈路程式碼和業務程式碼依然耦合在一起,進一步優化:

// 业务代码
const order500 = function(orderType, pay, stock) {
  if ( orderType === 1 && pay === true ) {
    console.log('500 元定金预购,得到 100 元优惠券')
  } else {
    return 'nextSuccess'
  }
}

const order200 = function(orderType, pay, stock) {
  if ( orderType === 2 && pay === true ) {
    console.log('200 元定金预购,得到 50 元优惠券')
  } else {
    return 'nextSuccess'
  }
}

const orderCommon = function(orderType, pay, stock) {
  if (orderType === 3 && stock > 0) {
    console.log('普通购买,无优惠券')
  } else {
    console.log('库存不够,无法购买')
  }
}

// 链路代码
const chain = function(fn) {
  this.fn = fn
  this.sucessor = null
}

chain.prototype.setNext = function(sucessor) {
  this.sucessor = sucessor
}

chain.prototype.init = function() {
  const result = this.fn.apply(this, arguments)
  if (result === 'nextSuccess') {
    this.sucessor.init.apply(this.sucessor, arguments)
  }
}

const order500New = new chain(order500)
const order200New = new chain(order200)
const orderCommonNew = new chain(orderCommon)

order500New.setNext(order200New)
order200New.setNext(orderCommonNew)

order500New.init( 3, true, 500 ) // 普通购买,无优惠券

重構後,鏈路程式碼和業務程式碼徹底分離。如果未來需要新增 order300,只需新增與其相關的函數而不必改動原有業務程式碼。

另外結合AOP 還能簡化上述連結程式碼:

// 业务代码
const order500 = function(orderType, pay, stock) {
  if ( orderType === 1 && pay === true ) {
    console.log('500 元定金预购,得到 100 元优惠券')
  } else {
    return 'nextSuccess'
  }
}

const order200 = function(orderType, pay, stock) {
  if ( orderType === 2 && pay === true ) {
    console.log('200 元定金预购,得到 50 元优惠券')
  } else {
    return 'nextSuccess'
  }
}

const orderCommon = function(orderType, pay, stock) {
  if (orderType === 3 && stock > 0) {
    console.log('普通购买,无优惠券')
  } else {
    console.log('库存不够,无法购买')
  }
}

// 链路代码
Function.prototype.after = function(fn) {
  const self = this
  return function() {
    const result = self.apply(self, arguments)
    if (result === 'nextSuccess') {
      return fn.apply(self, arguments) // 这里 return 别忘记了~
    }
  }
}

const order = order500.after(order200).after(orderCommon)

order( 3, true, 500 ) // 普通购买,无优惠券

職責鏈模式比較重要,專案中能用到它的地方會有很多,用上它能解耦1 個請求物件和n 個目標物件的關係。

相關推薦:

js設計模式:什麼是享元模式? js享元模式的介紹

js設計模式:什麼是範本方法模式? js模板方法模式的介紹

以上是js設計模式:什麼是職責鏈模式? js職責鏈模式的介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn