初面网初面网

责任链(职责链)模式

原视频:职责链模式

使多个对象都有机会处理请求,避免请求的发送者与多个接收者直接的耦合关系。

接收者连接成链条,请求会顺着链条依次寻找能够处理请求的对象

/*
<input type="text" id="input">
<button id="btn">注册</button>
*/

// 以下是糟糕代码的示例
// btn.onclick = function(){
//   if(input.value.length === 0){
//     console.log("不能为空")
//   }else{
//     if(Number.isNan(+input.value)){
//       console.log("必须是数字")
//     }else{
//       if(input.value.length<6){
//         console.log("必须大于6个数字")
//       }
//     }
//   }
// }

// 以下是职责链模式
btn.onclick = function(){
  new Chain(checkEmpty).check()
}
function checkEmpty(){
  if(input.value.length === 0){
    console.log("不能为空")
    return
  }
  return "next"
}

function checkNumber(){
  if(Number.isNan(+input.value)){
    console.log("必须是数字")
    return
  }
  return "next"
}

function checkLength(){
  if(input.value.length<6){
    console.log("必须大于6个数字")
    return
  }
  return "next"
}

class Chain{
  constructor(fn){
    this.checkRule = fn
    this.nextRule = null
  }

  addRule(nextRule){
    this.nextRule = nextRule
  }

  check(){
    this.checkRule() === "next"? this.nextRule.check():null
  }
}

const checks = new Chain(checkEmpty)
const checkNumberChain = new Chain(checkNumber)
const checkLengthChain = new Chain(checkLength)
checks.addRule(checkNumberChain)
checkNumberChain.addRule(checkLengthChain)
checkLengthChain.addRule({
  check: () => "end"
})
  • 改进版
btn.onclick = function(){
  new Chain(checkEmpty).check()
}
function checkEmpty(){
  if(input.value.length === 0){
    console.log("不能为空")
    return
  }
  return "next"
}

function checkNumber(){
  if(Number.isNan(+input.value)){
    console.log("必须是数字")
    return
  }
  return "next"
}

function checkLength(){
  if(input.value.length<6){
    console.log("必须大于6个数字")
    return
  }
  return "next"
}

class Chain{
  constructor(fn){
    this.checkRule = fn
    this.nextRule = null
  }

  addRule(nextRule){
    this.nextRule = new Chain(nextRule)
    return this.nextRule
  }

  endRule(){
    this.nextRule = {
      check:() => "end"
    }
  }

  check(){
    this.checkRule() === "next"? this.nextRule.check():null
  }
}

const checks = new Chain(checkEmpty)
checks.addRule(checkNumber).addRule(checkLength).endRule()

更新于 2025/2/26