簡體   English   中英

Java 從 function 返回時,變量被分配了某個值 跟進

[英]Java return from function when variable gets assigned a certain value FOLLOW UP

這是我的第一個問題的后續問題
如果變量(函數內部)在任何時候被分配了某個值,是否可以留下 function。 這次是任務之間的動作。 例如:

public class TestClass {
    public int doSomething(Message message) {
        int resultCode;
        
        resultCode = checkFirstThing(message) //Returns 0 if succeed or 1 if not
        //Exit if resultCode != 0
        
        //do something with message

        Permission perm = message.author.perm

        resultCode = checkSecondThing(perm) //Returns 0 if succeed or 2 if not
        //Exit if resultCode != 0

        //Excecute something

        resultCode = checkThirdThing() //Returns 0 if succeed or 3 if not
        //Exit if resultCode != 0

        //do Something if resultCode still 0
        return resultCode
    }
}

我的問題是,我不想在每個 Check-Function 之后添加if(resultCode != 0) return resultCode ,因為這將是重復的代碼。

坦克為您提供幫助:)

經常在OOP中,如果不想重復代碼,就為它設計一個class。 在這種情況下,它也適用。

讓我們從

public class Result {

    private int code;

    public Result(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public boolean isSuccess() {
        return 0 == code;
    }

}

因此,您 retrofit 您的其他方法返回Result實例而不是原始int

public Result checkFirstThing(/* parameters */) {
    // implementation
}

public Result checkSecondThing(/* parameters */) {
    // implementation
}

...

在這一點上,我們並沒有收獲太多, doSomething方法看起來大致相同。 但是,請查看Result class 的以下方法

public Result and(Supplier<? extends Result> code) {
    return isSuccess() ? code.get() : this;
}

此方法本質上在其自身和作為Supplier傳入的代碼的指定部分之間執行惰性 AND 連接。

更正式地說,如果這個Result表示一個成功的結果,指定的代碼將被執行並返回它的結果。 否則,這個Result表示錯誤的結果,指定的代碼將不會被執行,這個Result將簡單地返回自己。

您現在可以使用此方法將您的方法調用鏈接在一起,而無需添加任何if語句。

public int doSomething(Message message) {
    Result result = checkFirstThing(/* parameters */)
         .and(() -> checkSecondThing(/* parameters */))
         .and(() -> checkThirdThing(/* parameters */));
    if (result.isSuccess()) {
        /* 
         * Do your actual processing. You could also add your main processing 
         * to the method chain above, but I think like this it is more clear
         * for future reading.
         */
    }
    return result.getCode();
}

處理中間語句

我不太喜歡副作用或較長方法鏈之間的任何語句。 但是,在您的示例中,您可以簡單地訪問 model 中的一個字段,所以讓我們看看這看起來像一個中間操作

Message message = null;
// iniialize message
Result result = checkFirstThing(message).and(() -> {
    Permission perm = message.author.perm;
    return checkSecondThing(perm).and(() -> checkThirdThing(perm));
});

如果發現這比簡單地將Permission perm = message.author.perm復制到相應的check...方法中的可讀性要低得多。

讓所有檢查方法都基於Message的實例也使它們更加簡潔,因為它們都基於相同(類型)的輸入,因此為了將來的閱讀,可以同時快速評估所有方法的合同。 否則,如果某些方法基於Message而某些方法基於Permission ,則未來的讀者將不得不“解密”上述方法鏈,以便了解正在評估消息的哪個權限。

但是,為了在這一點上恢復一些可修改性,您可以將方法鏈的內部部分提取到一個新方法中

private Result checkAuthorPermissions(Message message) {
    Permission perm = message.author.perm;
    return checkSecondThing(perm).and(() -> checkThirdThing(perm));
}

並且簡單地做

Result result = checkFirstThing(message)
     .and(() -> checkAuthorPermissions(message));

嘗試這個。

class SomethingException extends Exception {
    public final int resultCode;
    SomethingException(int resultCode) {
        this.resultCode = resultCode;
    }
}

void checkResultCode(int resultCode) throws SomethingException {
    if (resultCode != 0)
        throw new SomethingException(resultCode);
}

public int doSomething(Message message) {
    try {
        checkResultCode(checkFirstThing(message));
        //Exit if resultCode != 0            
        //do something with message          
        Permission perm = message.author.perm;
        checkResultCode(checkSecondThing(perm));
        //Exit if resultCode != 0
        //Excecute something
        checkResultCode(checkThirdThing());
        //Exit if resultCode != 0
        //do Something if resultCode still 0
        return 0;
    } catch (SomethingException e) {
        return e.resultCode;
    }
}

暫無
暫無

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

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