我想如果你稍微改变一下你对情况的看法,你会更容易解决这个问题:
- 您正在处理框架,我们称其为外部框架。
- 另一方面,您正在为框架编写一个包装器 - 内部框架。
- 您的代码(客户端应用程序)使用内部框架,假设它提供用于问题域的功能。据我了解,并且我相信,客户端应用程序不应该对外部框架有任何想法。
现在,问题归结为以下一个问题:内部框架的功能是否明确概述并最终确定?还是这也在改变?
如果它正在改变(可能是因为外部框架),那么内部框架正在开发中。这意味着,客户端应用程序需要等到内部框架准备好宣布第一个版本准备就绪(可能在外部框架完成之后)。
现在错误处理:
应用程序中的错误就像合同一样。函数的调用者只期望特定的异常情况和特定类型的错误。每个可能的错误都由每个函数预定义和记录,类似于它的输入参数和返回值。
这对您意味着什么:
- 定义内部框架的最终设计(越早越好)。
- 决定内部框架的每个函数可以抛出什么样的错误。
- 使用客户端应用程序的内部框架,只期望预期和记录的异常。不要尝试/捕获内部框架不期望的任何内容。基本上,遵守合同。
- 如果错误代码发生变化,则不会改变内部框架中函数的概念。它仍然需要抛出它之前抛出的相同类型的错误(根据合同)。唯一需要更改的部分是,如何将新代码转换为预期的(约定的)错误之一。你可以用任何更好的方法来解决它。
为什么最后一个假设是好的?因为我们说过内部应用程序的设计是最终的,不会改变。错误合约也是最终设计的一部分。
例子:
//external.
int Say(char* message);
//internal.
///<summary>
/// can throw (CONTRACT): WrongMessageException, SessionTimeOutException
void Say(string message) {
int errorCode = External.Say(message);
//translate error code to either WrongMessageException or to SessionTimeOutException.
}
不能翻译?当前的约定错误或外部框架有问题:也许您应该终止该过程?出事了,没想到!!!
//client.
...
try {
Internal.Say("Hello");
}
catch (WrongMessageException wme) {
//deal with wrong message situation.
}
catch (SessionTimeOutException stoe) {
//deal with session timeout situation.
}
让我知道是否有任何问题。
将错误代码转换为异常:
这显然是对每个错误代码的某种分类。类别可以是每个目的地异常,并且可以按功能对异常进行分类。这正是错误合约的含义:按功能对异常进行分类;并按异常对错误代码进行分类。
下面是一个伪配置。以此作为如何分类的初步想法:
category Say [can throw]: { WrongMessageException, SessionTimeOutException }
category WrongMessageException [by error code]: { 100, 101 }
category SessionTimeOutException [by error code]: { 102, 103, 104 }
当然,您不需要为这种印象编写解析器(这是人类可读的伪配置)。您可以使用 XML 或任何类型的源存储类似的句子,这将帮助您配置错误翻译规则和函数契约。
参考
书籍:Jeffrey Richter - CLR 通过 C#,第 3 版。第 20 章 - 异常和状态管理。子章 - 指南和最佳实践。Sub-Sub-Chapter - 隐藏实施细节以维护“合同”。
本章将把异常描述为契约,并将解释如何对函数抛出的契约进行分类。这可以确认这里提供的解释的正确性和可信度。