10

我有一个与正确处理我正在为一个项目编写的 DAO 库的返回有关的问题。这个库可能会被其他人使用,我想正确地做到这一点。我应该如何处理我的 DAO 函数的返回语句?

示例 1 我有 getCustomer 函数,它应该返回字符串。如果查询没有返回任何结果,我应该返回 null、空字符串还是抛出某种异常?

示例 2 我有一个函数 ,getCutomerList它返回一个 ArrayList<String> 类型的值。如果查询没有返回任何结果,我应该返回 null、空的 ArrayList 还是抛出一些异常?

示例 3 检测到一些 SQL 异常,我应该怎么做,抛出异常或对可能发生的块执行try.. ?catch

适用于我的案例的“良好”做法或“最佳”做法是什么?

4

4 回答 4

10

看来您的图书馆正在进行类似数据库的调用。如果是这种情况,那么我将完全按照JPA 2 规范实现。

我的意思是,查看JPAfind() API 中的方法并准确返回他们在那里所做的事情。

    /**
     * Find by primary key.
     * @param entityClass
     * @param primaryKey
     * @return the found entity instance or null
     *    if the entity does not exist
     * @throws IllegalStateException if this EntityManager has been closed.
     * @throws IllegalArgumentException if the first argument does
     *    not denote an entity type or the second
     *    argument is not a valid type for that
     *    entity's primary key
     */
    public <T> T find(Class<T> entityClass, Object primaryKey);

您在此处看到find,我认为这与您的方法相似,如果找不到,getCustomer()它将返回,并且仅在参数无效时才抛出。nullIllegalArgumentException

如果该find()方法与您想要的方法不接近,您应该实现与getSingleResult()getCustomer()相同的行为:

    /**
     * Execute a SELECT query that returns a single result.
     * @return the result
     * @throws EntityNotFoundException if there is no result
     * @throws NonUniqueResultException if more than one result
     * @throws IllegalStateException if called for a Java 
     *    Persistence query language UPDATE or DELETE statement
     */
    public Object getSingleResult();

EntityNotFoundException如果没有找到结果,NonUniqueResultException如果找到多个实例或IllegalStateExceptionSQL 错误,则会抛出。

你必须决定哪种行为最适合你。

getResultList()也是如此:

/**
 * Execute a SELECT query and return the query results
 * as a List.
 * @return a list of the results
 * @throws IllegalStateException if called for a Java 
 *    Persistence query language UPDATE or DELETE statement
 */   
public List getResultList();

getResultList()如果没有找到,将返回 null 并且仅在 SQL 非法时抛出异常。

通过遵循这种行为,您将保持一致,并且您的用户会感觉了解图书馆的情况。


另一种行为是返回一个空集合而不是null. 这就是Google Guava实现其 API 的方式,这确实是首选原因。但是,我喜欢一致性,并且仍然认为您应该尽可能接近实现该库standard


资源

Joshua Bloch 制作了一段视频,解释如何设计一个好的 API 以及它为什么重要

于 2011-02-07T14:59:25.587 回答
2
  1. 空值。但是方法getCustomer()应该返回客户。如果它返回 String 它可能应该被调用getCustomerName()getCustomerId()
  2. 空列表
  3. 抛出异常。可能用应用层异常包装它。
于 2011-02-07T15:01:39.890 回答
1

示例 1:由于没有检索到任何内容,因此应返回 null。或者,可以选择Null-Object 模式。

示例 2:首选空 ArrayList 而非null。参见“Effective Java”第 43 条:返回空数组或集合,而不是 null

示例 3:将 SQLException 转换为更高的 Exception 并抛出它。参见“Effective Java”第 61 条:抛出适合抽象的异常

于 2011-02-07T15:01:29.453 回答
1

由于它是您的 API,因此只要您保持一致并确保正确记录它,任何方法都是好的。

对于 1 和 2:请注意,返回 null 将强制客户端代码继续执行如下检查:

result = yourAPICall();
if(result != null){
   // do something
}

这就是为什么我更喜欢返回空对象或集合

对于 3:这将取决于您的 API 设计。但首先,永远不要在调用堆栈中抛出低级异常。您应该将它们包装在为您的 API 设计的自定义异常类中,以便您的客户端代码只需要捕获您的 API 异常而不是各种较低级别的异常(SQLException、IOException 等...)

其次,您必须首先确定抛出异常是否有任何好处。抛出异常允许客户端代码自定义它希望如何处理其 API 依赖项遇到的问题。但是抛出它也会阻止你作为 API 设计者设计内部突发事件,这将使你的代码可能从问题中恢复(使你的 API 不那么健壮)

于 2011-02-18T11:01:31.613 回答