You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何减少reducer中switch非空case数量解决SonarQube代码异味问题

解决方案

针对你遇到的SonarQube限制switch非空case数量的问题,有两种改动成本低、完全兼容原有逻辑的优化方案:

方案1:用对象映射表替换switch语句(改动最小,优先推荐)

你的所有case逻辑都是固定的action.type到处理函数的映射,直接用键值对对象存储映射关系即可,完全规避switch case数量限制,逻辑和原有代码100%等价,上线零风险。

实现代码:

// 定义Action处理函数的类型
type ActionHandler = (state: IEquipmentState, payload: any) => IEquipmentState

// 构建Action类型到处理函数的映射表
const actionHandlers: Partial<Record<EquipmentActionTypes, ActionHandler>> = {
  [EquipmentActionTypes.REQUEST_EQUIPMENT]: (state) => 
    reducerUtils.requestListData<IEquipmentState, IEquipment[]>(state, ['equipmentList']),
  [EquipmentActionTypes.RECEIVE_EQUIPMENT]: (state, payload) => 
    reducerUtils.receiveListData<IEquipmentState, IEquipment[]>(state, ['equipmentList'], payload),
  [EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT]: (state, payload) => 
    reducerUtils.errorListData<IEquipmentState, IEquipment[]>(state, ['equipmentList'], payload),

  [EquipmentActionTypes.REQUEST_EQUIPMENT_BY_ID]: (state) => 
    reducerUtils.requestItemData<IEquipmentState, IEquipment>(state, ['selectedEquipment']),
  [EquipmentActionTypes.RECEIVE_EQUIPMENT_BY_ID]: (state, payload) => 
    reducerUtils.receiveItemData<IEquipmentState, IEquipment>(state, ['selectedEquipment'], payload as IEquipment),
  [EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT_BY_ID]: (state, payload) => 
    reducerUtils.errorItemData<IEquipmentState, IEquipment>(state, ['selectedEquipment'], payload),

  // 剩余所有Action的处理逻辑依次按上述格式添加即可
  [EquipmentActionTypes.RESET_STATE]: (state) => resetSelectedEquipmentState(state)
}

export function equipmentReducer(
  lastState: IEquipmentState = new EquipmentState(),
  action: GenericAction<EquipmentActionTypes, any>
): IEquipmentState {
  // 匹配到对应处理函数则执行,否则返回原state,等价于原有switch的default逻辑
  return actionHandlers[action.type]?.(lastState, action.payload) ?? lastState
}

进阶优化:批量生成映射表

你的处理逻辑高度模式化,所有Action都遵循请求/接收/错误的三段式结构,仅参数不同,可以进一步封装批量生成逻辑,减少重复代码:

// 先定义所有业务实体的配置项
const entityConfigs = [
  {
    prefix: 'EQUIPMENT',
    statePath: ['equipmentList'],
    isList: true,
    dataType: {} as IEquipment[]
  },
  {
    prefix: 'EQUIPMENT_BY_ID',
    statePath: ['selectedEquipment'],
    isList: false,
    dataType: {} as IEquipment
  },
  // 依次添加所有业务实体的配置:INITIAL_SPECIFICATION、MANUFACTURERS、SUPPLIERS等
]

// 批量生成handler
entityConfigs.forEach(config => {
  const reqType = EquipmentActionTypes[`REQUEST_${config.prefix}` as keyof typeof EquipmentActionTypes]
  const resType = EquipmentActionTypes[`RECEIVE_${config.prefix}` as keyof typeof EquipmentActionTypes]
  const errType = EquipmentActionTypes[`ERROR_RECEIVE_${config.prefix}` as keyof typeof EquipmentActionTypes]

  actionHandlers[reqType] = (state) => config.isList 
    ? reducerUtils.requestListData(state, config.statePath)
    : reducerUtils.requestItemData(state, config.statePath)
  
  actionHandlers[resType] = (state, payload) => config.isList
    ? reducerUtils.receiveListData(state, config.statePath, payload)
    : reducerUtils.receiveItemData(state, config.statePath, payload)

  actionHandlers[errType] = (state, payload) => config.isList
    ? reducerUtils.errorListData(state, config.statePath, payload)
    : reducerUtils.errorItemData(state, config.statePath, payload)
})

后续新增业务Action只需要加一行配置即可,无需重复写处理逻辑。

方案2:按业务模块拆分reducer

你当前的reducer包含了设备、厂商、供应商、联系人多个独立业务逻辑,可以按业务拆分成多个子reducer,每个子reducer的case数量都远低于30,符合SonarQube规则的同时也提升了代码可维护性。

实现示例:

// 拆分设备核心业务reducer
function equipmentCoreReducer(state: IEquipmentState, action: GenericAction<EquipmentActionTypes, any>): IEquipmentState {
  switch(action.type) {
    // 只处理设备本身的相关case,数量不超过30
    case EquipmentActionTypes.REQUEST_EQUIPMENT:
    case EquipmentActionTypes.RECEIVE_EQUIPMENT:
    case EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT:
    // 其他设备核心相关case
    default: return state
  }
}

// 拆分厂商业务reducer
function manufacturerReducer(state: IEquipmentState, action: GenericAction<EquipmentActionTypes, any>): IEquipmentState {
  switch(action.type) {
    // 只处理厂商相关的case
    case EquipmentActionTypes.REQUEST_MANUFACTURERS:
    case EquipmentActionTypes.RECEIVE_MANUFACTURERS:
    case EquipmentActionTypes.ERROR_RECEIVE_MANUFACTURERS:
    // 其他厂商相关case
    default: return state
  }
}

// 同理拆分供应商、联系人等业务的reducer

// 组合子reducer
export function equipmentReducer(
  lastState: IEquipmentState = new EquipmentState(),
  action: GenericAction<EquipmentActionTypes, any>
): IEquipmentState {
  let state = lastState
  state = equipmentCoreReducer(state, action)
  state = manufacturerReducer(state, action)
  state = supplierReducer(state, action)
  state = contactReducer(state, action)
  return state
}

方案选择建议

  • 仅需要快速修复SonarQube问题、不想改动现有逻辑:选方案1,1小时内即可完成改造
  • 后续还会持续新增业务Action、希望优化代码可维护性:选方案2,长期收益更高

内容的提问来源于stack exchange,提问作者simpller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:36:03