【问题标题】:Is return boolean for operation success / fail a good practice in Java?操作成功/失败的返回布尔值是Java中的一个好习惯吗?
【发布时间】:2015-02-25 14:19:30
【问题描述】:

我有一些功能适用于数据库。 我在这里设置了一个 try/catch 用于错误处理,并显示一条消息,它工作正常。

现在调用这个删除函数的类需要知道是否有错误。在我的情况下:如果成功则刷新 GUI,如果失败则什么都不做(因为已经显示了一个消息消息对话框)。

我想出了一个在这个函数中返回布尔值的想法。

public static Boolean delete(int id){

    String id2 = Integer.toString(id);
    try {
        String sql = 
                "DELETE FROM toDoItem " +
                "WHERE id = ?;";
        String[] values = {id2};
        SQLiteConnection.start();
        SQLiteConnection.updateWithPara(sql, values);
    } catch (SQLException e) {
        Main.getGui().alert("Fail when doing delete in DataBase.");
        System.out.println("Exception : "+ e.getMessage());
        return false;
    }
    return true;
}

不知道是好是坏,请告诉。


编辑:

这里是我如何使用的更多细节:

假设上面的代码在 A 类中, B类:

public boolean deleteItem(int id){
    int i = index.get(id);
    if(theList[i].delete()){  //<---- here is the function from Class A
        theList[i] = null;
        index.remove(id);
        retutn true;
    }
    retutn false; 
}

我需要在不止一个类中传递布尔值,我不知道这是否可以更好地通过......

C 类:

public void toDoList_deleteItem(){
    MyButton btn = (MyButton)source;
    int id = btn.getRefId();
    List toDoList = Main.getToDoList();
    if(toDoList.deleteItem(id)){  //<-------function in Class B
        Main.getGui().refresh();
    }
}

编辑 2:

我注意到这个问题更有可能是在问“我应该如何处理影响 GUI 层的数据库层的异常?”......类似的事情。如果应该编辑问题标题,请纠正我。

【问题讨论】:

  • 这取决于你。你会如何处理返回值?

标签: java


【解决方案1】:

当您预计不会失败时,应使用异常。

在您的情况下,如果抛出 SQLException 并且不影响您的程序对您来说没问题,则可以返回布尔值。

如果导致删除失败的 SQLExcetion 可能导致应用程序的另一部分出现问题,则最好抛出异常。

编辑:

根据您的编辑,当发生错误时,您似乎正在进行一些维护和清理工作。在这种情况下,我建议使用 Exceptions 比使用布尔值来控制执行更好。

【讨论】:

    【解决方案2】:

    您似乎正在返回 boolean 状态以指示发生了异常情况。一般来说,这不是一个好的做法,原因有两个:

    • 它鼓励一种容易出错的异常处理方式 - 很容易错过状态检查,从而导致错误被忽略
    • 它限制了 API 报告错误的能力 - 单个通过/失败位并不总是足够的,可能需要传递有关错误的更多信息。

    更好的方法是定义一个特定于应用程序的异常,并在您的 API 中使用它。这迫使您的 API 用户注意可能发生的异常情况,同时让您传递尽可能多(或尽可能少)您认为必要的附加信息。同时,您的代码不会在每次 API 调用时被 if (!delete(id)) { /* handle error */ } 代码污染,从而缩小代码库并提高其可读性。

    你能告诉我更多关于“定义一个特定于应用程序的异常”的信息吗,或者请展示一些代码示例?

    我会这样做:

    public class DataAccessException extends Exception {
        ... // Define getters/setters for passing more info about the problem
    }
    ...
    public static void delete(int id) throws DataAccessException {
        try {
            ... // Do something that may lead to SQLException
        } catch (SQLException se) {
            // Do additional logging etc., then
            throw new DataAccessException("Error deleting "+id, se);
        }
    }
    

    注意:通常为自定义异常提供四个镜像Exception 类的构造函数以允许异常链接。构造函数描述为here

    【讨论】:

    • 完美答案。 +1 指出 为什么 这是一个坏主意。
    • 你能告诉我更多关于“定义一个特定于应用程序的异常”的信息,或者显示一些代码示例吗?虽然没有if (!delete(id)) { /* handle error */ },但我需要在函数的第一行添加throws MyOwnException,对吗?
    • @user3662467 你为什么不研究那个话题?网上会有很多资料。如果您选择检查异常,则在您不想处理它的链上每个方法中都需要 throws MyOwnException
    • +1。我同意..在大多数一般情况下,最好使用特定于应用程序的异常..只要我们以某种方式使用它:P
    • 不错。我建议你修改这个例子,给DataAccessException一个构造函数,这样异常就可以被链接起来。
    【解决方案3】:

    只要你不希望调用者知道发生了什么,只是它失败了(失败是它预期行为的一部分)你应该没问题。

    话虽如此,我注意到了这一点:Main.getGui().alert("Fail when doing delete in DataBase.");

    您似乎正在从其他地方访问 GUI 层。如果您决定对应用程序进行多线程处理,这可能会导致问题。此外,您的图层不相交通常被认为是一种很好的做法。

    【讨论】:

    • 感谢您告诉我致电Main.getGui().alert() 应该考虑更多。
    • 理想情况下,您的方法仍会返回异常。如果您不想提供额外的数据,您可以创建自己的异常并抛出它。这样,调用层(可能是 UI)就可以处理和显示它认为合适的任何消息。
    【解决方案4】:

    不要返回Boolean,而是返回boolean。由于这不是 异常/错误 条件,所以没问题。

    【讨论】:

    • 第 1 部分 +1,第 2 部分 -0.4。这可能不是错误情况,但如果必须适当处理(这取决于程序),则异常可能确实是合适的。
    • @glglgl - 他编辑的代码是if(theList[i].delete()){ 它使 sebse 返回真或假而不是抛出异常。他最终也在调用者中做同样的事情
    • 我不同意您的“因为这不是异常/错误情况,所以没问题”的说法,因此我投了反对票。对我来说,很明显 OP 滥用布尔返回值来代替适当的异常处理。
    • @Duncan - 在我的例子中:如果成功则刷新 GUI,如果失败则什么也不做(因为那里已经显示了一个消息消息对话框)。。 OP 实际上是在处理一个异常,但不是 传播 它很好。为什么要发送另一个 catch 块并在调用者中做同样的事情? ..顺便说一句+1实际上告诉我你为什么投反对票:P
    • @TheLostMind 这是真的,我猜。但是我会争辩说,从数据库层内接触 GUI 并不是最佳实践。我也不认为当所有进一步的数据库访问都可能中断时让应用程序继续跛行并不是一个很好的设计。
    【解决方案5】:

    这个问题主要是基于意见的。就我个人而言,我不希望此时捕获异常。

    根据delete()caller 应该做什么,您可能需要其他结果。所以你最好添加一个 throw 语句,让调用方法来决定错误是否严重 - 或者它是否可以继续。

    仅仅truefalse 不足以让调用者做出正确决定。他不知道删除是否由于数据库错误、外键约束或其他原因而失败。

    让异常在调用堆栈中冒泡将为调用者提供正在发生的确切错误,增加以正确方式处理错误的机会,或者仅显示自定义错误消息以帮助用户采取正确的措施。

    【讨论】:

    • 感谢详细解释。
    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 2023-02-15
    • 2016-01-03
    • 1970-01-01
    • 2012-05-07
    相关资源
    最近更新 更多