如何降低以下代码的声纳认知复杂度?
How to reduce the cognitive complexity of sonar for the below code?
下面是我的代码,Sonar 抱怨它。要求做 15,现在是 19。重构此方法以将其认知复杂度从 19 降低到允许的 15。我尝试使用无法正常工作的枚举。它的 transactionId 作为 RequestParam。是否有任何eclipse工具可以提取这个或者我们需要手动提取。
@GetMapping(value = "display",produces = APPLICATION_JSON_VALUE)
@ResponseBody
public List<RspNotification> display(@RequestParam(name = Constants.TRANSACTION_ID) final String transactionId)
{
List<RspNotification> list = new ArrayList<>();
if (manageProductOrderCISStore.get(transactionId) != null)
{
list.add(manageProductOrderCISStore.get(transactionId));
}
else if (manageAppointmentWWMStore.get(transactionId) != null)
{
list.add(manageAppointmentWWMStore.get(transactionId));
}
else if (manageAppointmentHWMStore.get(transactionId) != null)
{
list.add(manageAppointmentHWMStore.get(transactionId));
}
else if (manageAppointmentUnifyStore.get(transactionId) != null)
{
list.add(manageAppointmentUnifyStore.get(transactionId));
}
else if (manageAppointmentUnifyXmlStore.get(transactionId) != null)
{
list.add(manageAppointmentUnifyXmlStore.get(transactionId));
}
else if (manageProductOrderFLSStore.get(transactionId) != null)
{
list.add(manageProductOrderFLSStore.get(transactionId));
}
else if (manageProductOrderHFSStore.get(transactionId) != null)
{
list.add(manageProductOrderHFSStore.get(transactionId));
}
else if (fulfilmentQuoteEEStore.get(transactionId) != null)
{
list.add(fulfilmentQuoteEEStore.get(transactionId));
}
else if (manageInventoryHFSStore.get(transactionId) != null)
{
list.add(manageInventoryHFSStore.get(transactionId));
}
else if (manageInventoryFLSStore.get(transactionId) != null)
{
list.add(manageInventoryFLSStore.get(transactionId));
}
else if (manageBillingDocumentStore.get(transactionId) != null)
{
list.add(manageBillingDocumentStore.get(transactionId));
}
else if (serviceHealthStore.get(transactionId) != null)
{
list.add(serviceHealthStore.get(transactionId));
}
else if (fulfilmentOrderEEStore.get(transactionId) != null)
{
list.add(fulfilmentOrderEEStore.get(transactionId));
}
else if (manageWorkOrderUnifyStore.get(transactionId) != null)
{
list.add(manageWorkOrderUnifyStore.get(transactionId));
}
else if (manageDiagnosticAssuranceStore.get(transactionId) != null)
{
list.add(manageDiagnosticAssuranceStore.get(transactionId));
}
else if (materialsSupplyUnifyStore.get(transactionId) != null)
{
list.add(materialsSupplyUnifyStore.get(transactionId));
}
///////// more if statement
return list;
}
非常感谢任何帮助,枚举将不起作用。
将所有这些词典放在一个列表中。 运行 尝试从每个项目中提取密钥并将其添加到列表中的循环。
列出地图并遍历它们
List<Map<String, RspNotification>> maps = Arrays.asList(
manageProductOrderCISStore,
manageAppointmentWWMStore,
manageAppointmentHWMStore,
manageAppointmentUnifyStore
//the rest
);
List<RspNotification> list = new ArrayList<>();
for (Map<String, RspNotification> map : maps) {
RspNotification notification = map.get(transactionId);
if (notification != null) {
list.add(notification);
return;
}
}
return list;
你可以进一步简化为
return Stream.of(
manageProductOrderCISStore,
manageAppointmentWWMStore,
manageAppointmentHWMStore,
manageAppointmentUnifyStore
//the rest
)
.map(map -> map.get(transactionId))
.filter(Objects::nonNull)
.findFirst()
.map(Collections::singletonList)
.orElse(Collections.emptyList());
我看到了 3 种可能性:
- 遍历只有一个 if 的商店列表 - 如果你能有一个共同的 superclass/interface,它可能是最好的
- 拆分 ifs:假设在 10 之后,您调用 else {另一个方法与其余的 ifs}
- 告诉声纳接受这个(是的,你可以这样做)
我认为实际上可以在声纳中添加关于这个的例外,因为在我看来,另一个会使代码更难阅读。
下面是我的代码,Sonar 抱怨它。要求做 15,现在是 19。重构此方法以将其认知复杂度从 19 降低到允许的 15。我尝试使用无法正常工作的枚举。它的 transactionId 作为 RequestParam。是否有任何eclipse工具可以提取这个或者我们需要手动提取。
@GetMapping(value = "display",produces = APPLICATION_JSON_VALUE)
@ResponseBody
public List<RspNotification> display(@RequestParam(name = Constants.TRANSACTION_ID) final String transactionId)
{
List<RspNotification> list = new ArrayList<>();
if (manageProductOrderCISStore.get(transactionId) != null)
{
list.add(manageProductOrderCISStore.get(transactionId));
}
else if (manageAppointmentWWMStore.get(transactionId) != null)
{
list.add(manageAppointmentWWMStore.get(transactionId));
}
else if (manageAppointmentHWMStore.get(transactionId) != null)
{
list.add(manageAppointmentHWMStore.get(transactionId));
}
else if (manageAppointmentUnifyStore.get(transactionId) != null)
{
list.add(manageAppointmentUnifyStore.get(transactionId));
}
else if (manageAppointmentUnifyXmlStore.get(transactionId) != null)
{
list.add(manageAppointmentUnifyXmlStore.get(transactionId));
}
else if (manageProductOrderFLSStore.get(transactionId) != null)
{
list.add(manageProductOrderFLSStore.get(transactionId));
}
else if (manageProductOrderHFSStore.get(transactionId) != null)
{
list.add(manageProductOrderHFSStore.get(transactionId));
}
else if (fulfilmentQuoteEEStore.get(transactionId) != null)
{
list.add(fulfilmentQuoteEEStore.get(transactionId));
}
else if (manageInventoryHFSStore.get(transactionId) != null)
{
list.add(manageInventoryHFSStore.get(transactionId));
}
else if (manageInventoryFLSStore.get(transactionId) != null)
{
list.add(manageInventoryFLSStore.get(transactionId));
}
else if (manageBillingDocumentStore.get(transactionId) != null)
{
list.add(manageBillingDocumentStore.get(transactionId));
}
else if (serviceHealthStore.get(transactionId) != null)
{
list.add(serviceHealthStore.get(transactionId));
}
else if (fulfilmentOrderEEStore.get(transactionId) != null)
{
list.add(fulfilmentOrderEEStore.get(transactionId));
}
else if (manageWorkOrderUnifyStore.get(transactionId) != null)
{
list.add(manageWorkOrderUnifyStore.get(transactionId));
}
else if (manageDiagnosticAssuranceStore.get(transactionId) != null)
{
list.add(manageDiagnosticAssuranceStore.get(transactionId));
}
else if (materialsSupplyUnifyStore.get(transactionId) != null)
{
list.add(materialsSupplyUnifyStore.get(transactionId));
}
///////// more if statement
return list;
}
非常感谢任何帮助,枚举将不起作用。
将所有这些词典放在一个列表中。 运行 尝试从每个项目中提取密钥并将其添加到列表中的循环。
列出地图并遍历它们
List<Map<String, RspNotification>> maps = Arrays.asList(
manageProductOrderCISStore,
manageAppointmentWWMStore,
manageAppointmentHWMStore,
manageAppointmentUnifyStore
//the rest
);
List<RspNotification> list = new ArrayList<>();
for (Map<String, RspNotification> map : maps) {
RspNotification notification = map.get(transactionId);
if (notification != null) {
list.add(notification);
return;
}
}
return list;
你可以进一步简化为
return Stream.of(
manageProductOrderCISStore,
manageAppointmentWWMStore,
manageAppointmentHWMStore,
manageAppointmentUnifyStore
//the rest
)
.map(map -> map.get(transactionId))
.filter(Objects::nonNull)
.findFirst()
.map(Collections::singletonList)
.orElse(Collections.emptyList());
我看到了 3 种可能性:
- 遍历只有一个 if 的商店列表 - 如果你能有一个共同的 superclass/interface,它可能是最好的
- 拆分 ifs:假设在 10 之后,您调用 else {另一个方法与其余的 ifs}
- 告诉声纳接受这个(是的,你可以这样做)
我认为实际上可以在声纳中添加关于这个的例外,因为在我看来,另一个会使代码更难阅读。