如何减少if-else深度?

时间:2017-10-25 03:51:47

标签: coding-style code-cleanup

我有这个示例代码

public static ActionProcessable getActionProcessor(TaskType currentTaskType, UserAction userAction){
    String actionKey;
    if(userAction != null){
        if(currentTaskType != null){
            actionKey = buildKey(currentTaskType, userAction);
            if(dossierActions.containsKey(actionKey)){
                return dossierActions.get(actionKey);
            }
        }

        actionKey = buildKey(anyTaskType(), userAction);
        if(dossierActions.containsKey(actionKey)){
            return dossierActions.get(actionKey);
        }
    }

    return new NullActionProcessor();
}

在这个逻辑中,我有一个映射,用于通过组合键TaskType和UserAction存储ActionProcessable。此方法将返回带有输入taskType和action的ActionProcessable。 TaskType可以为null,因此在这种情况下我们只需要通过userAction获取。

当我通过声纳检查此代码时,它会说第三个如果是"嵌套if-else depth是2(允许的最大值是1)"

但我不知道如何让它变得更好。 有人建议我吗?

1 个答案:

答案 0 :(得分:1)

您可以将“if containsKey”部分移出条件以删除代码重复:

public static ActionProcessable getActionProcessor(TaskType currentTaskType, UserAction userAction){
    if (userAction != null) {
        String actionKey = currentTaskType != null
            ? buildKey(currentTaskType, userAction)
            : buildKey(anyTaskType(), userAction);

        if (dossierActions.containsKey(actionKey)){
            return dossierActions.get(actionKey);
        }
    }

    return new NullActionProcessor();
}

现在,代码的意图看起来更清晰(至少对我而言)

你也可以使第一个条件短路和\或使用三元组,如果containsKey,它将删除更多if,但可能会使代码对某些人来说更复杂。

public static ActionProcessable getActionProcessor(TaskType currentTaskType, UserAction userAction){
    if (userAction == null) { 
        return new NullActionProcessor();
    }

    String actionKey = currentTaskType != null
        ? buildKey(currentTaskType, userAction)
        : buildKey(anyTaskType(), userAction);

    return dossierActions.containsKey(actionKey)
        ? dossierActions.get(actionKey);
        : new NullActionProcessor();
}

选择您喜欢的,技术上相似。

由于您尚未指定特定的编程语言,还有一件事要说:您的代码是null-coalsecing运算符用例的一个很好的例子。可悲的是,AFAIK,Java中没有。在C#中,代码可能如下所示:

public static ActionProcessable GetActionProcessor(TaskType currentTaskType, UserAction userAction) {
    if (userAction == null) { 
        return new NullActionProcessor();
    }

    var actionKey = BuildKey(currentTaskType ?? anyTaskType(), userAction);
    return dossierActions[actionKey] ?? new NullActionProcessor();
}