降低 if-else 语句代码的复杂性

Reducing complexity of code for if-else statements

我的代码分析插件抱怨包含以下代码的方法中的代码复杂性。我注意到下面的代码看起来可以组合,但我不知道该怎么做:

for(Command command : commands) {
    if (command instanceof AddCommand || command instanceof UpdateCommand) {
        if (!isMaturityDateInPast() && !paymentDueDate().isAfter(LocalDate.now())) {
            command.execute(request);
        }
    } else {
        command.execute(request);
    }
}

我尝试引入布尔变量并在 if 和 else 语句中设置它,但这只会增加更多代码行。 在逻辑上放置具有共同点的代码部分时,我不是很好。我知道这个 if-else 可以组合,但我不知道该怎么做。有人可以解释一下吗?

我将尝试将其拆分为多个方法,因为这将使其更具可读性并降低方法的复杂性。示例:

       for(Command command : commands) {
            if (command instanceof AddCommand || command instanceof UpdateCommand) {
                checkAndExecuteCommand(command,request);

            } else {
                command.execute(request);
            }
        }

        private void checkAndExecuteCommand(Command command,Request request) {
            if (!isMaturityDateInPast() && !paymentDueDate().isAfter(LocalDate.now())) {
                command.execute(request);
            }
        }

我会早点 continue 以避免重复 command.execute()。 我认为不值得将条件组合在一起或为此创建另一个函数。

for(Command command : commands) {
  if (command instanceof AddCommand || command instanceof UpdateCommand) {
    if (isMaturityDateInPast() || paymentDueDate().isAfter(LocalDate.now())) {
        continue;
    }
  }
  command.execute();
}

您可以通过否定第一个条件然后将其与第二个条件相或来合并两个相同的分支。

那个和两个小的 util 方法使代码更漂亮:

for (Command command : commands) {
    if (!isAddOrUpdate(command) || executeAnyway()) {
        command.execute(request);
    }
}   

private static boolean isAddOrUpdate(Command command) {
    return command instanceof AddCommand || command instanceof UpdateCommand;
}

// Rename this to something that makes sense for your domain
private boolean  executeAnyway(){
    return !isMaturityDateInPast() && !paymentDueDate().isAfter(LocalDate.now());
}

如果您检查 不是 AddCommandUpdateCommand 的命令,您可以获得稍微更简洁的代码:

for(Command command : commands) {
    if (!(command instanceof AddCommand || command instanceof UpdateCommand)) {
        command.execute(request);
    } else if(!isMaturityDateInPast() && !paymentDueDate().isAfter(LocalDate.now())) {
            command.execute(request);
    }
}

但这充其量只是稍微好一点。嵌套 if 子句真的没有错。事实上,实际上这是嵌套在 else 子句中的 if 子句,但由于 Java(与许多其他语言一样)允许使用 else if 语法糖,因此 看起来 清洁工.

您可以进一步模块化您的代码(分解为单独的方法)。这可能会使它更 readable/maintainable 并且应该安抚静态分析。

此外,您可能只需要对每次迭代执行一些检查(因为输入似乎没有改变)。

它也可能有助于创建一些更具可读性和"explain"你正在做什么的布尔值。

boolean isMaturityDateInFuture = !isMaturityDateInPast();
boolean isPaymentDueDateInPast = !paymentDueDate().isAfter(LocalDate.now());

for (Command command : commands) {
    boolean isAddOrUpdate = command instanceof AddCommand || command instanceof UpdateCommand;

    if (!isAddOrUpdate || (isMaturityDateInFuture && isPaymentDueDateInPast)) {
        command.execute(request);
    }
}