preface

The chain of responsibility pattern is very common in our development, but for those of you who don’t know, you may have implemented similar logic in the if/else way before. The chain of responsibility mainly refers to the process of chain judgment when the implementation of a specific thing is uncertain about which logic to use until the function or object that meets the conditions is found and then processed. Analysis, found that in fact, the logic behind a lot of our code is the responsibility chain pattern.

The illustration

The chain of responsibility in reality

In reality, there are many examples. For example, when we are crowded in a bus, if there are too many people, we pass coins through people and pass them forward until the person in front is the driver or conductor. This is a very obvious example of responsibility chain.

Code refactoring

The original code was basically doing constant judgments with if and else, doing different logic.

Case description

Before the refactoring

const order = (orderType,pay,stock){
	if(orderType === 1) {if(pay === true) {console.log('500 yuan deposit, 100 coupons returned ')}else {
    	if(stock > 0 ){
      	consle.log('Regular purchase, no coupons')}else {
      	console.log('Understock')}}}else if(orderType === 2) {if(pay === true) {console.log('200 yuan deposit, 50 coupons returned ')}else {
    	if(stock > 0 ){
      	consle.log('Regular purchase, no coupons')}else {
      	console.log('Understock')}}}else{
   	if(stock > 0 ){
      	consle.log('Regular purchase, no coupons')}else {
      	console.log('Understock')}}}Copy the code

After the reconstruction

In accordance with the design idea of responsibility chain, we have reached the position in one step, including the following ideas:

  • Encapsulate the different purchase patterns as functions
  • Implementation of chain function, can continue to add functions, can be inconsistent, implementation of submission
const order500 = function(orderType,pay,stock){
	if(orderType === 1 && pay === true) {console.log('500 yuan deposit, 100 coupons returned ')}else {
    	return 'nextSuccessor'; }}const order200 = function(orderType,pay,stock){
	if(orderType === 2 && pay === true) {console.log('200 yuan deposit, 50 coupons returned ')}else {
    	return 'nextSuccessor'; }}const orderNormal = function(orderType,pay,stock){
	if(stock > 0) {console.log('Regular purchase, no coupons')}else {
      	console.log('Understock')}}const Chain = function(fn){
	this.fn = fn;
    this.successor = null;
}
Chain.prototype.setNextSuccessor = function(successor){
	return this.successor = successor;
}
Chain.prototype.passRequest = function(){
 let ret = this.fn.apply(this.arguments);
 if(ret === 'nextSuccessor') {return this.successor && this.successor.passRequest.apply(this.successor, arguments);
 }
 return ret;
}

let chainOrder500 = new Chain(order500);
let chainOrder200 = new Chain(order200);
let chainOrderNormal = new Chain(orderNormal);
chainOrder500.setNextSuccessor(chainOrder200);
chainOrder200.setNextSuccessor(chainOrderNormal);

chainOrder500.passRequest(1.false.0);
chainOrder500.passRequest(1.true.10);
chainOrder500.passRequest(2.true.11);
chainOrder500.passRequest(2.false.1);
Copy the code

Codepen address: codepen. IO /robinson90/…

Responsibilities driven Design and the practice of state patterns

The article links: mp.weixin.qq.com/s/qQEEnf79F…

demand

The solution

The responsibility driven concept is introduced to judge which object has the ability of operation from the perspective of knowledge ability.

However, the disadvantage of this is that when new states are added, all the state classes of the implementation interface need to be changed, which does not conform to the open and closed principle of design pattern.

State diagram:

Another kind of chain of responsibility

This is not in the typical chain of responsibility design. It is my own opinion in the development process, which also conforms to the formal chain judgment, but ultimately only determines the execution of a final function, rather than the implementation of chain delivery.

Of course, it may not belong to any design pattern at all, but I think the essence of a design pattern is to solve the fixed mindset of a fixed scene, and the name is not the point.

The specific code is as follows:

let Chain = function(){
  let dutyArr = []
	this.addDuty = function(duty){
    dutyArr.push(duty)
  }
  this.opt = function(params){
		for(let index in dutyArr){
    	if(dutyArr[index].judge(params)){
      	returndutyArr[index].opt && dutyArr[index].opt(params); }}return false}}let ageChainDemo = new Chain();
ageChainDemo.addDuty({
	judge:function(params){
    let {age} = params;
    return age > 18;
},
  opt:function(params){
    let {age} = params;
    return 'You're an adult now.'
  }
})

ageChainDemo.addDuty({
	judge:function(params){
    let {age} = params;
    return age > 0 && age < 18;
},
  opt:function(params){
    let {age} = params;
    return 'You're a minor.'}})let result = ageChainDemo.opt({age:20});
console.log(result);
let result2 =ageChainDemo.opt({age:10});
console.log(result2);
Copy the code

Codepen address: codepen. IO /robinson90/…

Differences from the policy pattern

At first glance, the chain of responsibility is written as nothing like the policy pattern, which maintains separate functional logic, with the main difference being the judgment of the use condition.

The policy pattern can determine exactly which policy to use and determine which strategy to use to return results; In the chain of responsibility mode, the use of conditions is abstracted and built into the function. Through continuous internal judgment of the function, if the function does not meet the requirements, the judgment needs to continue to pass until the function that meets the requirements is executed and executed.

From this, we can decide that if we are vague about the conditions, we are better off using the chain of responsibility. This is better than writing complex Booleans inside if/else, or using the result value of a computed variable, or using the return result of another function.

More and more

The original link: www.yuque.com/robinson/de…

More learning and understanding of the design patterns, can walk into my design pattern album: www.yuque.com/robinson/de…