1. 程式人生 > >【JS設計模式】責任鏈模式的程式碼示例

【JS設計模式】責任鏈模式的程式碼示例

責任鏈設計模式:

在責任鏈模式裡,很多物件由每一個物件對其下家的引用而連線起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個物件決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪一個物件最終處理這個請求,這使得系統可以在不影響客戶端的情況下動態地重新組織和分配責任。



責任鏈模式涉及到的角色如下所示:
● 抽象處理者(Handler)角色:定義出一個處理請求的介面。如果需要,介面可以定義 出一個方法以設定和返回對下家的引用。這個角色通常由一個Java抽象類或者Java介面實現。上圖中Handler類的聚合關係給出了具體子類對下家的引用,抽象方法handleRequest()規範了子類處理請求的操作。

● 具體處理者(ConcreteHandler)角色:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。


在JS(ES6之前)中嚴格意義上是沒有extends繼承概念,所以以下程式碼沒有模擬抽象類,程式碼中只實現了具體處理類.

使用場景:在一個購物商城,在五一做了一個活動,所以圖書類商品根據購買的金額依次做出以下折扣方案,
1、購買滿199元,打9折
2、購買滿399元,打8折
3、購買滿599元以上,打7折;

責任鏈鏈的優點:

請求傳送者只需要知道鏈中的第一個節點,從而弱化了傳送者和一組接收者之間的強聯絡。如果不使用責任鏈鏈模式、根據當前價格客戶端要知道每一級打折資訊,最後知道具體是那一層上打折才是符合當前價格的折扣。


function BookHandler() {
  this.calcPrice = function( price ) {
    if ( 199 > price ) {
      console.log("原價是:"+ price);
    } else {
      this.successor.calcPrice( price );
    }
  }
  this.setSuccessor = function( _successor ) {
    this.successor = _successor;
  }
}


function BookCalc9Handler( _successor ) {


  this.calcPrice = function( price ) {
    if ( 199 <= price && price < 399 ) {
      console.log("原價是:"+ price +";打9折後:" + (price * 0.9));
    } else {
      this.successor.calcPrice( price );
    }
  }
  this.setSuccessor = function( _successor ) {
    this.successor = _successor;
  }
}


function BookCalc8Handler() {


  this.calcPrice = function( price ) {
    if ( 399 <= price && price < 599 ) {
      console.log("原價是:"+ price +";打8折後:" + (price * 0.8));
    } else {
      this.successor.calcPrice( price )
    }
  }
  this.setSuccessor = function( _successor ) {
    this.successor = _successor;
  }
}


function BookCalc7Handler() {


  this.calcPrice = function( price ) {
    if ( price >= 599 ) {
      console.log("原價是:"+ price +";打7折後:" + (price * 0.7));
    } else {
      this.successor.calcPrice( price )
    }
  }
  this.setSuccessor = function( _successor ) {
    this.successor = _successor;
  }
}



客戶端 :

var price = 400;
var bookHandler = new BookHandler();
var bookCalc9Handler = new BookCalc9Handler();
var bookCalc8Handler = new BookCalc8Handler();
var bookCalc7Handler = new BookCalc7Handler();


bookHandler.setSuccessor(bookCalc9Handler);
bookCalc9Handler.setSuccessor(bookCalc8Handler);
bookCalc8Handler.setSuccessor(bookCalc7Handler);
bookHandler.calcPrice(price);

Console.log打印出來的效果: