为什么存储库模式的示例永远不会处理数据库连接异常?

时间:2015-05-07 21:59:22

标签: architecture exception-handling repository-pattern

我已经阅读了很多教程,并看到了很多关于Repository模式实现的代码示例。几乎在每种情况下,都不会解决因数据库不可用时尝试访问数据库而导致的异常。考虑到如果数据库位于网络上的某个位置,这是一个非常现实的情况,这似乎很奇怪。

那么处理这些异常的最佳做法是什么?

  • 在try / catch中包含这100个调用中的每一个,每个调用都可能有 相同的 n 捕获块?这有很多重复,混乱,容易出错等等。

  • 让异常冒泡到应用程序级别,抓住它们 未处理的例外?如果在UI线程上抛出异常,这是有意义的,否则,处理未处理的AppDomain异常会导致应用程序关闭。

  • 使用Enterprise Library&Exception等框架 处理申请阻止?

2 个答案:

答案 0 :(得分:3)

老实说,我认为它没有得到解决,因为关于如何处理异常的持续(和情感)辩论。关于是否应该在本地处理异常(在更有可能理解它们并执行某些智能操作,例如重试)或在UI层处理(其中99.9%的异常最终冒泡),有一个常见的来回。

就个人而言,我发现在Repository层中执行try / catch是最优雅的,以捕获特定于数据库的异常,并抛出我自己制作的新异常。这给了我一个放置重试逻辑的地方。然后,我还可以决定DAOException是已检查还是运行时异常。

这允许用户界面处理已知异常,并帮助我将更高级别的层与任何特定于提供者的错误隔离开来。例如,如果我将数据存储迁移到像Mongo或Cassandra这样的No-SQL数据库,我仍然可以抛出相同的异常,并保持其语义,而不会更改所有调用代码。

答案 1 :(得分:1)

首先,因为SRP。一个班级只处理一个而且只承担一个责任。至少在一种方法中。

其次,这取决于你需要对失败做些什么。您只会向用户显示错误消息吗? 在应用程序级别处理,因为数据级别和业务级别不知道有哪些UI。

如果您有逻辑,例如:如果无法访问数据库,请使用脱机缓存,使用Decorator pattern或类似方法处理它,例如:

public class OnlineUserRepository : IUserRepository{
    public User Get(){ /* get the user from online source */ }
}

public class OfflineUserRepository : IUserRepository{
    public User Get(){ /* get the user from offline source */ }
}

public class UserRepository : IUserRepository{
    public UserRepository(IUserRepository onlineRepo, IUserRepository offlineRepo){
        //parameter assignment
    }
    IUserRepository onlineRepo;
    IUserRepository offlineRepo;
    public User Get(){
        try{
            onlineRepo.Get();
        }
        catch{
            return offlineRepo.Get();
        }
    }
}

为什么我们需要这样处理呢?再次,因为SRP