正确处理返回数据[关闭]
Posted
技术标签:
【中文标题】正确处理返回数据[关闭]【英文标题】:Correct handling of return data [closed] 【发布时间】:2011-06-22 19:13:40 【问题描述】:我有一个关于正确处理我正在为一个项目编写的 DAO 库的返回的问题。这个库可能会被其他人使用,我想正确地做到这一点。我应该如何处理我的 DAO 函数的返回语句?
示例 1 我有 getCustomer 的函数,它应该返回字符串。如果查询没有返回任何结果,我应该返回 null、空字符串还是抛出某种异常?
示例 2
我有一个函数getCutomerList
,它返回一个ArrayList
示例 3
检测到一些SQL异常,我该怎么办,抛出异常还是try
..catch
的块可以发生呢?
在我的案例中应用的“良好”做法或“最佳”做法是什么?
【问题讨论】:
【参考方案1】:看来您的库正在执行类似数据库的调用。如果是这种情况,那么我将完全按照JPA 2 specification 的方式执行。
我的意思是,查看JPA API 中的find()
方法并准确返回他们在那里所做的事情。
/**
* 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()
方法,如果没有找到它将返回null
,如果参数无效则只抛出IllegalArgumentException
。
如果find()
方法与getCustomer()
的方法不接近,您应该实现与getSingleResult() 相同的行为:
/**
* 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
,如果SQL 错误则抛出IllegalStateException
。
你必须决定哪种行为最适合你。
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 made a video explaining how to design a good API and why it matters.
【讨论】:
请注意,javadoc 与 jpa 2 api 并不完全相同,但行为相似 好吧,在没有找到元素的情况下抛出特殊异常似乎很有说服力,并且杀死参数 :P 是用户对 api 感到满意。非常感谢您的帮助:) 另请阅读我给您的资源链接,如果您愿意,请记住将答案标记为已接受 100% 被接受 ;) 很好的答案。 一个关于错字的快速说明:对于 getSingleResult,您的解释列出了 EntityNotFoundException 两次。第二个应该是 NonUniqueResultException。仍然,一个惊人的答案。 +1。【参考方案2】:-
空。但是方法
getCustomer()
应该返回客户。如果它返回字符串,它可能应该被称为getCustomerName()
或getCustomerId()
空列表
抛出异常。可能用应用层异常包装它。
【讨论】:
+1 表示getCustomer
应该返回一个对象。否则null
可能会模棱两可。客户名称是空的,还是找不到客户?
好的,我的函数更多的是 getCustomerName 然后是 getCustomer,显然我会返回 Customer 而不是 String ;) 但无论如何感谢指出那个失误【参考方案3】:
示例 1:由于没有检索到任何内容,因此应返回 null。或者,Null-Object 模式 可以作为一种选择。
示例 2:首选 empty ArrayList 而不是 null。参见“Effective Java”第 43 条:返回空数组或集合,而不是空值
示例 3:将 SQLException 转换为更高的 Exception 并抛出它。参见“Effective Java”第 61 条:抛出适合抽象的异常
【讨论】:
使用 Null-Object 模式的有趣方法,需要更仔细地了解这一点。感谢您指出对 Effective Java 的引用【参考方案4】:既然它是你的 API,任何方法都是好的,只要你保持一致并确保它被正确记录。
对于 1 和 2: 但请注意,返回 null 将强制客户端代码继续执行如下检查:
result = yourAPICall();
if(result != null)
// do something
这就是为什么我更喜欢返回空对象或集合
对于 3: 这将取决于您的 API 设计。但首先,永远不要在调用堆栈中抛出低级异常。您应该将它们包装在为您的 API 设计的自定义异常类中,以便您的客户端代码只需要捕获您的 API 异常,而不是各种较低级别的异常(SQLException、IOException 等)
其次,您必须首先确定抛出异常是否有任何好处。抛出异常允许客户端代码自定义它希望如何处理其 API 依赖项遇到的问题。但是抛出它也会阻止作为 API 设计者的您设计内部突发事件,从而让您的代码可能从问题中恢复(使您的 API 不那么健壮)
【讨论】:
对于 3,我创建了自定义异常,例如 ElemenetNotFoundException,以及一些与连接相关的异常,正在由 api 处理。无论如何感谢您的建议:-)以上是关于正确处理返回数据[关闭]的主要内容,如果未能解决你的问题,请参考以下文章