通常,我用更高级别、更有意义的异常来包装较低级别的异常。这通常需要更多的工作,但可以让您在层之间解耦。
想象一下,我正在编写一个恰好从数据库读取的配置子系统。如果我不包装,我会有类似的东西:
public String getConfigurationProperty(String name) throws SQLException {
// Try to read from my configuration table
}
如果我做包装,我会
public String getConfigurationProperty(String name) throws ConfigurationException {
try {
// Try to read from my configuration table
} catch (SQLException ex) {
ConfigurationException wrapper = // Some subclass of ConfigurationException that wraps ex
throw wrapper;
}
}
这肯定是更多的工作。优点是,如果以后我想将我的配置后端更改为基于文件的后端,没有包装器,我的方法将变为
public String getConfigurationProperty(String name) throws IOException {
// Try to read from my configuration file
}
然后我将不得不更改我的所有客户端代码以处理IOException
s 而不是SQLException
s。如果您进行包装,您只需要更改后端,因为您的客户端代码已经在编写时考虑了ConfigurationException
s 及其子类。请注意,这与您使用已检查或未检查的异常无关:如果您想要进行异常处理,您几乎总是需要至少知道要处理的异常类型的一些近似值。
现在,这就是我倾向于做的事情。有人认为无论如何都无法正确处理大多数异常,并且大多数情况下所有这些包装都是无稽之谈。
public String getConfigurationProperty(String name) throws ConfigurationException {
try {
// Try to read from my configuration file
} catch (IOException ex) {
ConfigurationException wrapper = // Some subclass of ConfigurationException that wraps ex
throw wrapper;
}
}