我正在开发一个java Web应用程序,我有一些关于设计的问题。
基本上在当前版本中,在很大程度上依赖于捕获异常以确定控制流。
例如,在我的一个Spring服务类中,我有以下方法来检查数据库中是否存在作为参数提供的电子邮件。
@Override
public boolean validateEmailAddressDoesNotExist(String accountEmailAddress) {
try {
return !dao.checkIfEmailAddressAlreadyExists(accountEmailAddress);
} catch (NoResultException re) {
log.error("NoResultException", re);
} catch (RuntimeException re) {
log.error("RuntimeException", re);
}
return true;
}
//from "dao" class
public boolean checkIfEmailAddressAlreadyExists(String accountEmailAddress) {
return (loadAccountFromAccountEmailAddress(accountEmailAddress) == null ? false : true);
}
//also from "dao" class
public Account loadAccountFromAccountEmailAddress(String accountEmailAddress) {
return entityManager.createNamedQuery("Account.findByEmailAddress", Account.class).setParameter("accountEmailAddress", accountEmailAddress).getSingleResult();
}
我怀疑我目前的设计可能不对,但我很高兴看到你对它的评论和意见以及你认为它有多大程度上存在缺陷。
答案 0 :(得分:4)
一般的经验法则是例外是针对“特殊”条件的。
因此,如果数据项可能存在,或者可能合理地缺席,那么返回布尔值会更正常。它通常也会产生更简单,更清晰的代码。
然后,您可以将异常保存为真正特殊的情况,例如网络故障等。
在某些情况下,第三方图书馆可能不会给你任何选择 - 如果他们抛出异常,那么你必须处理它们!
答案 1 :(得分:3)
我更喜欢从checkIfEmailAddressAlreadyExists等方法返回一个布尔值,并根据返回值简单地控制流,并将Exceptions保留为真正异常的条件,例如无法连接到数据库。
答案 2 :(得分:3)
服务模型中的验证方法不应该捕获异常。由于以下几个原因,这很糟糕:
这不是特例。 “没有结果”是一种常见的情况。
它间接地将验证与框架的数据检索方法的实现相结合。要想知道为什么这不好,想象一下如果你的框架发生变化,现在它会引发EmptyResultSetException
。您必须更新所有验证方法。糟糕!
如果您的基础框架引发异常以表明“没有结果”,那么您无法提供帮助,但您当然可以控制checkIfEmailAddressAlreadyExists
所做的事情。
更改此方法,以便在地址存在时返回true
,如果不存在,则返回false
。
答案 3 :(得分:1)
我不是Java程序员,实际上从未使用它。
但我确实知道在C#世界中提高和捕获异常是非常昂贵的。因此,使用它们来控制流程效率非常低,而不是自己检查事物,并为DNA所说的事情留下例外情况。