Skip to content

责任链模式 - executeChain 方法

在业务开发中,经常会遇到需要维护某个状态的需求,比如用户登录状态、用户授权状态、用户会员状态等等。通常,这些状态的判断逻辑比较统一,可以封装为一个方法来获取。然而,在面对特定场景下的状态定制化需求时,比如一个参与按钮的行为根据多种因素不同而异,就很容易产生一大堆复杂的 if-else 语句,这不仅影响代码的可读性,还不利于维护。

因此,我们提供了 executeChain 方法,它可以将一系列的判断逻辑与状态对应组装,从而提高代码的可读性和可维护性。

基本用法

首先,让我们比较一下以下两段代码,看哪一种更加优雅:

js
// 使用 if-else 方案
let message = ''

if (isActivityFinished) {
  message = '111'
} else if (!isLoginIn) {
  message = '222'
} else if (hasChange) {
  message = '333'
} else {
  message = '444'
}

// 使用 executeChain 方案
const message = executeChain([
  [isActivityFinished, '111'],
  [!isLoginIn, '222'],
  [hasChange, '333'],
  [true, '4444'],
])

这两种方案的差异可能在这个简单示例中不是很明显,但是在真实业务场景中,我们通常需要根据不同的状态展示不同的按钮,每个按钮的文案、样式、以及触发的事件都不同。这时候,代码可能会像下面这样变得更加复杂:

js
const btn = ({text, event = () => {}, disabled = false}) => ({
  text,
  event,
  disabled,
})

let activityBtn

if (isActivityFinished) {
  activityBtn = btn({
    text: '活动已结束',
    disabled: true,
  })
} else if (!isLoginIn) {
  activityBtn = btn({
    text: '去登录',
    event: () => {
      navToZAA()
    },
  })
} else if (hasChange) {
  activityBtn = btn({
    text: '回首页',
    event: () => {
      // 执行某些操作
    },
  })
} else {
  activityBtn = btn({
    text: 'Balabala..',
    event: () => {
      // 执行某些操作
    },
  })
}

如你所见,代码变得非常冗长和难以维护,如果情况更加复杂,拥有十几个 if-else 语句,代码将会变得非常混乱。这时候,我们再来看看 executeChain 的表现:

js
const activityBtn = executeChain([
  [
    isActivityFinished,
    btn({
      text: '活动已结束',
      disabled: true,
    }),
  ],

  [
    !isLoginIn,
    btn({
      text: '去登录',
      event: () => {
        navToZAA()
      },
    }),
  ],

  [
    hasChange,
    btn({
      text: '回首页',
      event: () => {
        // 执行某些操作
      },
    }),
  ],

  [
    true,
    btn({
      text: 'Balabala..',
      event: () => {
        // 执行某些操作
      },
    }),
  ],
])

这种方式看起来更加清晰和简洁,特别是在处理复杂情况时,优势更加明显。

进阶使用

当使用 executeChain 时,不要固守一种思维模式,不要生搬硬套。考虑以下情况:

js
let message = ''

if (isActivityFinished) {
  if (A) {
    message = '111'
  } else if (B) {
    message = '112'
  } else {
    message = '113'
  }
} else {
  if (!isLoginIn) {
    message = '222'
  } else if (hasChange) {
    message = '333'
  } else {
    message = '444'
  }
}

在这种情况下,不建议仍然使用单一责任链来解决问题,而应该将代码重构为以下方式:

js
let message = ''

if (isActivityFinished) {
  message = executeChain([
    [A, '111'],
    [B, '112'],
    [true, '113'],
  ])
} else {
  message = executeChain([
    [!isLoginIn, '222'],
    [hasChange, '333'],
    [true, '444'],
  ])
}

这样,即使存在更复杂的嵌套情况,也可以更加清晰地表达逻辑,提高代码的可维护性。

总结而言,executeChain 方法可以在处理多个状态和逻辑组合的情况下,提高代码的可读性和可维护性,使代码更加清晰和易于理解。

相关文档