我已经阅读了很多教程,并看到了很多关于Repository
模式实现的代码示例。几乎在每种情况下,都不会解决因数据库不可用时尝试访问数据库而导致的异常。考虑到如果数据库位于网络上的某个位置,这是一个非常现实的情况,这似乎很奇怪。
那么处理这些异常的最佳做法是什么?
在try / catch中包含这100个调用中的每一个,每个调用都可能有 相同的 n 捕获块?这有很多重复,混乱,容易出错等等。
让异常冒泡到应用程序级别,抓住它们 未处理的例外?如果在UI线程上抛出异常,这是有意义的,否则,处理未处理的AppDomain异常会导致应用程序关闭。
使用Enterprise Library&Exception等框架 处理申请阻止?
答案 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。