簡體   English   中英

降低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可以合並,但我不知道該怎么做。 有人可以解釋一下嗎?

我會盡早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句法糖,所以這看起來更清晰。

您可以將代碼模塊化一些(分解為單獨的方法)。 這可能使其更易讀/可維護,並應安撫靜態分析。

此外,當您可能只需要執行一次(因為輸入似乎沒有更改)時,您似乎可能會對每次迭代執行一些檢查。

它也可能有助於創建一些更易讀並且“解釋”你正在做什么的布爾值。

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);
    }
}

我將嘗試將其拆分為多個方法,因為這將使其更具可讀性並降低您的方法復雜性。 例:

       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);
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM