如果我的Dao图层抛出Dao特定异常,那么在我的服务层处理它们是否会引起关注?如果是,那么我应该使异常通用且独立于任何层来解决它,还是有其他方法?
同样的问题适用于服务层抛出的UI图层处理异常。
答案 0 :(得分:32)
当我们创建分层应用程序时,总会有一个用户层和另一个使用过的层。对于这种情况,UI层 - >使用服务层 - >使用DAO层。
现在它非常主观和开放的解释。但目标应该是良好的解耦程度。为实现这一目标,一种方法是定义泛型图层特定异常说PersistentException
,ServiceException
等。这些异常将包装实际的图层特定异常。
例如说如果数据库端存在某些错误(约束违规等),请将其包装在PersistentException中并让服务层处理该问题(关于如何将此传递到通用的UI层)方式)
现在,由于服务层和DAO层之间的集成是合同(基于接口),DAO层可以自由地将实现更改为任何内容,只要它服从接口合同。因此,如果您更改了抛出一些新异常的实现,那么这些新异常可以包含在PersistentException
中,服务层保持不受影响。
答案 1 :(得分:9)
是。为每个层创建自己的独立异常是一个好主意。
例如,如果您正在使用特定的DAO实现,则应将特定于实现的异常包装到您自己的通用异常中,并将其转发到服务层。
但是,您需要敏感地创建自己的异常层次结构,这样它不应该是应用程序开发的开销,也不应该能够维护服务层中所需的信息。大多数情况下,具有一般异常的自定义错误代码就足够了。
这样的东西可用于模拟特定于实现的异常并抛出到服务层。
class AppDAOException extends Exception {
public final static int _FAIL_TO_INSERT = 1;
public final static int _UPDATE_FAILED = 2;
public final static int _SQL_ERROR = 3;
private int errorCode;
public AppDAOException(int errorCode) {
this.errorCode = errorCode;
}
public getErrorCode() {
return errorCode;
}
}
从DAO实施中抛出:
try {
//code here
} catch (some.impl.SQLSyntaxException e) {
throw new AppDAOException (AppDAOException._SQL_ERROR );
}
关于泄密问题: 您可能不希望服务层对所有异常感到烦恼 - 例如:
} catch(NoRowExistsException e) {
return null;
} finally {
//release resources
}
因此必须根据应用需求进行调用。
答案 2 :(得分:6)
执行以下操作时,您的DAO图层已经泄漏到服务层:
userDAO.persist(user);
异常,作为API的一部分就像操作一样应该以同样的方式考虑。
try {
userDAO.persist(user);
} catch (DAOException e) {
// looks fine to me
}
运行时异常或重新抛出异常时可能会发生泄漏
try {
userDAO.persist(user);
} catch (SQLException e) {
// sql implementation exposed
}
但即使这听起来也比“独立于层”的例外更好
答案 3 :(得分:0)
好问题.. !! 在UI层处理异常(例如,如果使用struts,则为actions层)是一种很好的方法。将泛例设置为泛型并不是处理此问题的好方法。然而,每一层都应具有通用的特定例外。例如,DAO层可能具有自定义异常处理程序,如DavaSavingException,IOException等。
因此,该方法是从DAO向服务层抛出异常并再次将其抛出到UI层并捕获特定于UI的类。
然而,根据您的应用/需求,事情太过外交。