假设我有3层应用程序前端域和数据访问权限。我已经读过,在调用堆栈中捕获异常是个好主意...所以如果我得到一个数据访问异常,那么域层只会做一个finally,就像这样
尝试{
}最后{ //清理 }
并让数据访问异常渗透到前端层。这是不是通过使前端层处理内部而破坏分层?我认为每个层应该处理或包装并抛出它无法处理其调用层的异常...... 有什么想法吗?
答案 0 :(得分:1)
到目前为止,很多很好的反馈,我会给你我的看法。
规则#1。只捕获您将要实际处理的异常。通过句柄,我的意思是处理客户端的请求可以继续。您可能会捕获足够长的时间来记录信息(不要滥用它,通常堆栈是足够的信息)或转换为更容易传播的不同错误(基于运行时)。但是,如果你无法处理它,不要费心去抓它。这只是额外的代码,无用且令人困惑。即使您记录或转换,也最终会重新抛出。
实现大多数时候,你无法处理异常。真正做到。很多人都没有理解这一点。但实际情况是,如果你读取或写入磁盘的IOException,游戏结束。无法为用户完成该请求。如果您的网络不稳定而且您无法与数据库通信,那就相同。
规则#2。当你得到一个你无法处理的异常时,你唯一能做的就是尝试以对用户有帮助的方式失败。这意味着,记录它以供以后分析(包括原始堆栈/原因),然后向用户报告尽可能有用的内容。清理你必须的任何东西,以便系统保持一致的状态。
鉴于与最终用户的这种沟通发生在非常高的水平,这意味着你通常必须抓住那个级别。大多数时候,我发现在它的初始点和顶层之间的任何异常处理都没有什么价值,你可以捕获它来记录和报告给用户。我经常转换为RuntimeException的形式,但这只是为了简化层的传播。
最大也是最重要的是要意识到你通常无法处理异常,所以你为它们编写的代码应该尽可能简单。
答案 1 :(得分:0)
我不认为分层是一个纯粹的想法,这会破坏它。
包装和重新抛出也不会增加太多价值。
让服务层处理异常有什么问题?这应该是终点,最后一道防线。此设计允许服务记录异常 - 一劳永逸 - 并向UI发送用户友好消息以供显示。
答案 2 :(得分:0)
您通常希望在调用堆栈中捕获更高的异常,但仅限于有意义的点。如果数据级别可以处理和记录异常并只是将消息传递回前端,那么这将使事情变得简单和灵活。
就个人而言,如果我需要尝试和最后一次,那么我也想抓住并对那里的情况做些什么,而不是把它传递给调用者。请记住,好的设计规则总是有例外(通常是像KISS这样的另一个规则)。
答案 3 :(得分:0)
这里有三个互锁问题。
首先,可以不断重新包装异常,但它提供了什么价值?您只是围绕原始异常创建更多图层。当我可以提供有关异常的其他信息或第一个异常导致另一个异常时,我只包装异常。
其次,异常的想法是响应函数无法正常完成。您应该在最有效处理问题的地方捕获异常。如果代码具有“另一个替代”,则该异常应该被捕获。否则,请将其记录下来供用户或开发人员使用。
第三,try / finally块。当异常会导致资源在打开或分配状态下挂起时,这些操作非常有用。我总是使用try / finally来清理可能保持打开的资源(我最喜欢的是来自java.sql的Statement / ResultSet,一个巨大的内存耗尽)。一个非常优秀的程序员在他们的代码中有很多这样的方法,可以优雅地恢复而不会造成巨大的内存泄漏或资源限制。