职责链的使用

海龙2024-10-21编程JS/TS

职责链设计模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将请求沿着处理者链传递,直到有一个处理者能够处理该请求为止。这种模式的核心思想是解耦请求的发送者和接收者,使得多个对象都有机会处理请求,而无需明确指定具体的处理者。

以下是js版本的封装

// 职责链模式安装  将其扩展到Function的原型链上,方便使用
export function dutyChainInstall() {
  Function.prototype.dutyChain = function (fn) {
    const self = this
    return function (this: any, ...args) {
      const ret = self.apply(this, args)
      if (ret === 'nextSuccessor') {
        return fn.apply(this, args)
      }
      return ret
    }
  }
}
// 如果使用了ts 要在全局d.ts中去扩展类型
declare interface Function {
  dutyChain: (fn: any) => (...args: any) => any
}

根据对象的不同 需要不同的加工处理时,或者一个函数里 有很多if else的长链条时,可以使用职责链进行优化代码结构

使用示例

对于页面渲染要根据情况进行不同的处理时

职责链+自义定指令 让HTML部分以简单的方式去渲染,将不同情况的处理放在指令里。

import type { App } from 'vue'
// 联系方式隐藏指令
// 使用:
export function phoneHideInstall(app: App) {
  // 判断是否登录
  function isLogin(el: HTMLElement, arg: string, value: boolean) {
    // 未登录则向下进行
    if (!value) {
      return 'nextSuccessor'
    }
  }
  //   对联系人名字的处理
  function nameHide(el: HTMLElement, arg: string) {
    const text = el.innerText
    if (arg === 'name' && !el.innerText.includes('*')) {
      // 只保留第一个文字 其余部分文字变成*
      if (!text) return
      const num = text.length
      el.innerText = text.slice(0, 1) + '*'.repeat(num - 1)
    } else {
      return 'nextSuccessor'
    }
  }
  // 手机号处理
  function mobileHide(el: HTMLElement, arg: string) {
    const text = el.innerText
    // 判断是正常手机号 且没有被处理过的情况进行处理
    if (arg === 'phone' && !text.includes('-') && !text.includes('*')) {
      const hideText = text.slice(3, 7)
      el.innerHTML = text.replace(hideText, '****')
    } else {
      return 'nextSuccessor'
    }
  }
  //   座机号处理
  function landlineHide(el: HTMLElement, arg: string) {
    const text = el.innerText
    // 座机 以010-开头进行处理
    if (arg === 'phone' && !text.includes('*')) {
      const hideText = text.slice(5, 9)
      el.innerHTML = text.replace(hideText, '****')
    } else {
      return 'nextSuccessor'
    }
  }
  // 创造 隐藏手机号职责链
  const phoneChain = isLogin.dutyChain(nameHide)
    												.dutyChain(mobileHide)
    												.dutyChain(landlineHide)
  app.directive('phoneHide', (el, binding) => {
    // 职责链去执行判断
    phoneChain(el, binding.arg, binding.value)
  })
}

<span v-phone-hide:name='true'>12345678910</span>
<span v-phone-hide:phone='true'>12345678910</span>
<span v-phone-hide:phone='false'>010-12345678</span>
最后更新日期 6/24/2025, 10:29:18 AM