在服务层处理Dao异常

26
如果我的Dao层抛出Dao特定的异常,那么在服务层中处理它们是否构成了关注点泄漏?如果是的话,那么应该使异常通用并独立于任何层来解决这个问题,还是有其他方法?
同样的问题也适用于UI层处理服务层抛出的异常。
4个回答

37

创建分层应用程序时,总会有一个用户层和另一个被使用的层。对于此情况,UI层->使用服务层->使用DAO层。

现在这非常主观且可以解释开放。但目标应该是良好的解耦程度。为了实现这一点,其中一种方法是定义通用的层特定异常,例如PersistentExceptionServiceException等。这些异常将包装实际的层特定异常。

例如,如果在数据库端出现某些错误(约束违规等),则将其包装在PersistentException中,并让服务层处理它(如何以通用方式传达到UI层)。

现在,由于服务层和DAO层之间的集成合同性的(基于接口),因此DAO层可以自由更改实现方式,只要遵守接口契约就行。因此,如果更改实现会抛出一些新异常,则可以将这些新异常包装在PersistentException中,而服务层不受影响


请您能否提供一个关于此的例子...谢谢 - Shantaram Tupe
我之前写过一篇关于这个的文章。请查看https://dzone.com/articles/quotdecouplingquot-the-exception-puzzle - Santosh
@Santosh,在您上面的文章中,当异常冒泡时,您正在复制日志。因此,这是不好的做法。 - Java Main
@JavaMain,您能否把这个评论放在那篇文章下面吗?我会在那里回复。 - Santosh
当然,我会的。 - Java Main

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
}

因此,基于应用需求必须进行调用。

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
}

但即使这样听起来比“层无关”异常要好。

0

好问题..!! 在UI层处理异常(例如,如果您使用struts,则为操作层)是一个好方法。将异常变成通用的方式不是解决此问题的好方法。每个层次都应该有它们特定的异常作为通用的。例如,DAO层可能有自定义异常处理程序,如DavaSavingException、IOException等。

因此,方法是从DAO抛出异常到服务层,再将其抛回到UI层,并在UI特定类中捕获。

然而,这些事情太具有外交性,取决于您的应用程序/需求。


谢谢您的回答,但我还不清楚在服务层处理 DAO 异常是否构成了关注点泄漏,如果是,那么应该如何处理。 - shrini1000
“关注点泄漏”是什么意思?即使在服务层或DAO层中处理了DAO特定的异常,也可能不是一个问题。 - Ved
我的意思是:Dao异常可能包含特定于Dao问题的信息;如果服务层必须处理这些信息以处理异常,那么服务层不会与Dao层紧密耦合吗?这不会构成从Dao到服务的关注点泄漏吗? - shrini1000
可能是。但只有在处理信息时才会发生重大变化。 - Ved

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接