减少非空开关盒的数量

Posted

技术标签:

【中文标题】减少非空开关盒的数量【英文标题】:Reduce the number of non-empty switch cases 【发布时间】:2021-11-26 13:31:00 【问题描述】:

有没有办法像 SonarQube 所说的那样?在 reducer 文件中,一个 switch 中有 37 个 case,但 SonarQube 只允许 30 个。

也许可以用不同的方式编写我的代码,因为它运行良好,问题只是 SonarQube 像 CodeSmell 一样返回它。我在下面发布了我的减速器代码。

export function equipmentReducer(
  lastState: IEquipmentState = new EquipmentState(),
  action: GenericAction<EquipmentActionTypes, any>
): IEquipmentState 
    switch (action.type) 
        case EquipmentActionTypes.REQUEST_EQUIPMENT:
          return reducerUtils.requestListData<IEquipmentState, IEquipment[]>(lastState, ['equipmentList']);

    case EquipmentActionTypes.RECEIVE_EQUIPMENT:
      return reducerUtils.receiveListData<IEquipmentState, IEquipment[]>(lastState, ['equipmentList'], action.payload);

    case EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT:
      return reducerUtils.errorListData<IEquipmentState, IEquipment[]>(lastState, ['equipmentList'], action.payload);

    case EquipmentActionTypes.REQUEST_EQUIPMENT_BY_ID:
      return reducerUtils.requestItemData<IEquipmentState, IEquipment>(lastState, ['selectedEquipment']);

    case EquipmentActionTypes.RECEIVE_EQUIPMENT_BY_ID:
      return reducerUtils.receiveItemData<IEquipmentState, IEquipment>(
        lastState,
        ['selectedEquipment'],
        action.payload as IEquipment
      );

    case EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT_BY_ID:
      return reducerUtils.errorItemData<IEquipmentState, IEquipment>(lastState, ['selectedEquipment'], action.payload);

    case EquipmentActionTypes.REQUEST_ADD_EQUIPMENT:
    case EquipmentActionTypes.REQUEST_UPDATE_EQUIPMENT:
      return reducerUtils.requestPostPutItemData<IEquipmentState, IEquipment>(
        lastState,
        ['selectedEquipment'],
        action.payload
      );

    case EquipmentActionTypes.RECEIVE_ADD_EQUIPMENT:
    case EquipmentActionTypes.RECEIVE_UPDATE_EQUIPMENT:
      return reducerUtils.receivePostPutItemData<IEquipmentState, IEquipment>(
        lastState,
        ['selectedEquipment'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_ADD_EQUIPMENT:
    case EquipmentActionTypes.ERROR_UPDATE_EQUIPMENT:
      return reducerUtils.errorPostPutItemData<IEquipmentState, IEquipment>(
        lastState,
        ['selectedEquipment'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_INITIAL_SPECIFICATION:
      return reducerUtils.requestListData<IEquipmentState, IEquipmentInitialSpecification[]>(lastState, [
        'equipmentInitialSpecification',
      ]);

    case EquipmentActionTypes.RECEIVE_INITIAL_SPECIFICATION:
      return reducerUtils.receiveListData<IEquipmentState, IEquipmentInitialSpecification[]>(
        lastState,
        ['equipmentInitialSpecification'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_INITIAL_SPECIFICATION:
      return reducerUtils.errorListData<IEquipmentState, IEquipmentInitialSpecification[]>(
        lastState,
        ['equipmentInitialSpecification'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_MANUFACTURERS:
      return reducerUtils.requestListData<IEquipmentState, IManufacturersListItem[]>(lastState, [
        'manufacturers',
        'manufacturerList',
      ]);

    case EquipmentActionTypes.RECEIVE_MANUFACTURERS:
      return reducerUtils.receiveListData<IEquipmentState, IManufacturersListItem[]>(
        lastState,
        ['manufacturers', 'manufacturerList'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_RECEIVE_MANUFACTURERS:
      return reducerUtils.errorListData<IEquipmentState, IManufacturersListItem[]>(
        lastState,
        ['manufacturers', 'manufacturerList'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_SUPPLIERS:
      return reducerUtils.requestListData<IEquipmentState, ISuppliersListItem[]>(lastState, [
        'suppliers',
        'supplierList',
      ]);

    case EquipmentActionTypes.RECEIVE_SUPPLIERS:
      return reducerUtils.receiveListData<IEquipmentState, ISuppliersListItem[]>(
        lastState,
        ['suppliers', 'supplierList'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_RECEIVE_SUPPLIERS:
      return reducerUtils.errorListData<IEquipmentState, ISuppliersListItem[]>(
        lastState,
        ['suppliers', 'supplierList'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_ADD_MANUFACTURER:
      return reducerUtils.requestPostPutItemData<IEquipmentState, IManufacturer>(
        lastState,
        ['manufacturers', 'selectedManufacturer', 'manufacturerInfo'],
        action.payload
      );

    case EquipmentActionTypes.RECEIVE_ADD_MANUFACTURER:
      return reducerUtils.receivePostPutItemData<IEquipmentState, IManufacturer>(
        lastState,
        ['manufacturers', 'selectedManufacturer', 'manufacturerInfo'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_ADD_MANUFACTURER:
      return reducerUtils.errorPostPutItemData<IEquipmentState, IManufacturer>(
        lastState,
        ['manufacturers', 'selectedManufacturer', 'manufacturerInfo'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_ADD_SUPPLIER:
      return reducerUtils.requestPostPutItemData<IEquipmentState, ISupplier>(
        lastState,
        ['suppliers', 'selectedSupplier', 'supplierInfo'],
        action.payload
      );

    case EquipmentActionTypes.RECEIVE_ADD_SUPPLIER:
      return reducerUtils.receivePostPutItemData<IEquipmentState, ISupplier>(
        lastState,
        ['suppliers', 'selectedSupplier', 'supplierInfo'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_ADD_SUPPLIER:
      return reducerUtils.errorPostPutItemData<IEquipmentState, ISupplier>(
        lastState,
        ['suppliers', 'selectedSupplier', 'supplierInfo'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_ADD_MANUFACTURER_CONTACT:
      return reducerUtils.requestPostPutItemData<IEquipmentState, IContact>(
        lastState,
        ['manufacturers', 'selectedManufacturer', 'selectedContact'],
        action.payload
      );

    case EquipmentActionTypes.RECEIVE_ADD_MANUFACTURER_CONTACT:
      return reducerUtils.receivePostPutItemData<IEquipmentState, IContact>(
        lastState,
        ['manufacturers', 'selectedManufacturer', 'selectedContact'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_ADD_MANUFACTURER_CONTACT:
      return reducerUtils.errorPostPutItemData<IEquipmentState, IContact>(
        lastState,
        ['manufacturers', 'selectedManufacturer', 'selectedContact'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_ADD_SUPPLIER_CONTACT:
      return reducerUtils.requestPostPutItemData<IEquipmentState, IContact>(
        lastState,
        ['suppliers', 'selectedSupplier', 'selectedContact'],
        action.payload
      );

    case EquipmentActionTypes.RECEIVE_ADD_SUPPLIER_CONTACT:
      return reducerUtils.receivePostPutItemData<IEquipmentState, IContact>(
        lastState,
        ['suppliers', 'selectedSupplier', 'selectedContact'],
        action.payload
      );

    case EquipmentActionTypes.ERROR_ADD_SUPPLIER_CONTACT:
      return reducerUtils.errorPostPutItemData<IEquipmentState, IContact>(
        lastState,
        ['suppliers', 'selectedSupplier', 'selectedContact'],
        action.payload
      );

    case EquipmentActionTypes.REQUEST_EQUIPMENT_DELETE:
      return reducerUtils.requestPostPutItemData<IEquipmentState, IEquipment>(lastState, ['deletedEquipment'], action.payload);

    case EquipmentActionTypes.RECEIVE_EQUIPMENT_DELETE:
      return reducerUtils.receivePostPutItemData<IEquipmentState, IEquipment>(lastState, ['deletedEquipment'], action.payload);

    case EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT_DELETE:
      return reducerUtils.errorPostPutItemData<IEquipmentState, IEquipment>(lastState, ['deletedEquipment'], action.payload);

    case EquipmentActionTypes.REQUEST_EQUIPMENT_IS_DELETED:
      return requestItemData<IEquipmentState, boolean>(lastState, ['equipmentIsDeleted']);

    case EquipmentActionTypes.RECEIVE_EQUIPMENT_IS_DELETED:
      return receiveItemData<IEquipmentState, boolean>(lastState, ['equipmentIsDeleted'], action.payload);

    case EquipmentActionTypes.ERROR_RECEIVE_EQUIPMENT_IS_DELETED:
      return errorItemData<IEquipmentState, boolean>(lastState, ['equipmentIsDeleted'], action.payload);

    case EquipmentActionTypes.RESET_STATE:
      return resetSelectedEquipmentState(lastState);

    default:
      return lastState;
  

【问题讨论】:

请分享您的代码 @depperm 我分享了它。 您可以编辑 sonarqube 的规则或创建自己的规则吗? @depperm 不,我不是。 EquipmentActionTypes 字符串、整数等的值是什么? 【参考方案1】:

我相信你可以通过寻找共同的回报和创建地图来减少它。例如,reducerUtils.requestListData 被调用了 5 次,通过为差异创建地图,您应该能够摆脱 4 个 switch 案例。

最初的想法是把共享返回函数的action.types变成一个新的map(myMap)键并在这里列出具体的不同参数(我使用option1option2,因为我不知道其余代码)。使用option1 的替代方法是将其更改为unknown| (IEquipment[] | IEq....) 在&lt;&gt; 内的可能性列表

const myMap = 
    [EquipmentActionTypes.REQUEST_EQUIPMENT]: 
      option1: IEquipment[],
      option2: ['equipmentList']
    ,
    [EquipmentActionTypes.REQUEST_INITIAL_SPECIFICATION]: 
      option1: IEquipmentInitialSpecification[],
      option2: ['equipmentInitialSpecification']
    ,
    [EquipmentActionTypes.REQUEST_INITIAL_SPECIFICATION]: 
      option1: IEquipmentInitialSpecification[],
      option2: [
        'equipmentInitialSpecification',
      ]
    ,
    [EquipmentActionTypes.REQUEST_MANUFACTURERS]: 
      option1: IManufacturersListItem[],
      option2: [
        'manufacturers',
        'manufacturerList',
      ]
    ,
    [EquipmentActionTypes.REQUEST_SUPPLIERS]: 
      option1: ISuppliersListItem[],
      option2: [
        'suppliers',
        'supplierList',
      ]
    
  
  switch (action.type) 

    case EquipmentActionTypes.REQUEST_INITIAL_SPECIFICATION:
    case EquipmentActionTypes.REQUEST_MANUFACTURERS:
    case EquipmentActionTypes.REQUEST_SUPPLIERS:
    case EquipmentActionTypes.REQUEST_INITIAL_SPECIFICATION:
    case EquipmentActionTypes.REQUEST_EQUIPMENT:
      // alternatively instead of option1            ..... , unknown >
      // alternatively instead of option1            ..... , IEquipment[] | IEq.... >
      return reducerUtils.requestListData < IEquipmentState, myMap[action.type].option1 > (lastState, myMap[action.type].option2);

继续上面的想法,应该可以将函数移动到option1 并完全删除开关盒。相关article或this one

const myMap = 
    [EquipmentActionTypes.REQUEST_EQUIPMENT]:
        option1: reducerUtils.requestListData<IEquipmentState, IEquipment[] >(),
        option2: ['equipmentList']
    ,
    ...

myMap[action.type].option1(lastState, myMap[action.type].option2, actionPayload)

【讨论】:

这不起作用。我已经使用 NgRX 中的 combineReducers 解决了这个问题,方法是将大减速器分成两个较小的减速器。 @simpller 什么没用?它有错误吗?是不是把switch case的数量减少得不够多? 无法从 myMap 数组中获取类型 您是否尝试过替代方案:未知或| 我已经用 NgRx 的 combineReducers 修复了这个问题

以上是关于减少非空开关盒的数量的主要内容,如果未能解决你的问题,请参考以下文章

开关盒的样式

带有内部开关盒的单元测试 API 调用

Swift中开关盒的详尽条件

使用开关盒的三个数字中的最大值[关闭]

什么是大型开关盒的好替代品?

Java - 如何在开关盒中存储数组