Home  >  Article  >  Web Front-end  >  js design pattern: what is the chain of responsibility pattern? Introduction to js chain of responsibility model

js design pattern: what is the chain of responsibility pattern? Introduction to js chain of responsibility model

不言
不言Original
2018-08-17 16:43:571390browse

This article brings you content about js design patterns: What is the chain of responsibility pattern? The introduction of js chain of responsibility model has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

What is the chain of responsibility model?

##Importance: 4 stars, can optimize if-else statements in the project

Definition: Avoid coupling the request sender and receiver, make it possible for multiple objects to receive the request, connect these objects into a chain, and pass the request along this chain until an object handles it.

Main solution: The processor on the responsibility chain is responsible for processing the request. The customer only needs to send the request to the responsibility chain, and does not need to care about the request processing details and request delivery, so The chain of responsibility decouples the request sender from the request handler.

When to use: To filter many channels when processing messages.

How to solve:The intercepted classes all implement the unified interface.

js chain of responsibility model application examples: 1. "Blowing drums and passing flowers" in Dream of Red Mansions. 2. Event bubbling in JS. 3. The processing of Encoding by Apache Tomcat in JAVA WEB, the interceptor of Struts2, and the Filter of jsp servlet.

Advantages of js chain of responsibility model: 1. Reduce coupling. It decouples the sender and receiver of the request. 2. Simplified objects. The object does not need to know the structure of the chain. 3. Enhance the flexibility of assigning responsibilities to objects. Allows dynamic addition or deletion of responsibilities by changing members within the chain or moving their order. 4. It is very convenient to add new request processing classes.

Disadvantages of js chain of responsibility model: 1. There is no guarantee that the request will be received. 2. System performance will be affected to a certain extent, and it is inconvenient to debug the code, which may cause loop calls. 3. It may be difficult to observe runtime characteristics, which hinders debugging.

js chain of responsibility mode usage scenarios: 1. There are multiple objects that can handle the same request. The specific object that handles the request is automatically determined at runtime. 2. Submit a request to one of multiple objects without explicitly specifying the recipient. 3. A group of objects can be dynamically designated to handle requests.

js Chain of Responsibility Model Scenario

Scenario: An e-commerce company has a preferential policy for users who have paid a deposit. After the official purchase, users who have paid a deposit of 500 yuan will receive 100 yuan. Yuan coupons, users who make a deposit of 200 Yuan can receive 50 Yuan coupons, and users who have not paid a deposit can only purchase normally.

// 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 ) // 普通购买,无优惠券

The following uses the chain of responsibility model to improve the code

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 ) // 普通购买,无优惠券

After the transformation, you can find that the code is relatively clear, but the link code and business code are still coupled together for further optimization:

// 业务代码
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 ) // 普通购买,无优惠券

After reconstruction, the link code and business code are completely separated. If you need to add order300 in the future, you only need to add functions related to it without changing the original business code.

In addition, combining with AOP can also simplify the above link code:

// 业务代码
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 ) // 普通购买,无优惠券

The responsibility chain model is more important. There will be many places where it can be used in the project. It can decouple 1 The relationship between the request object and n target objects.

Related recommendations:

js design pattern: What is the flyweight pattern? Introduction to js flyweight pattern

#js design pattern: What is the template method pattern? Introduction to js template method pattern

The above is the detailed content of js design pattern: what is the chain of responsibility pattern? Introduction to js chain of responsibility model. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn