.NET 设计:冒泡异常以更好地重构实体消费者,这是一种好习惯吗?

Posted

技术标签:

【中文标题】.NET 设计:冒泡异常以更好地重构实体消费者,这是一种好习惯吗?【英文标题】:.NET Design: Bubbling up exceptions to better refactor entity consumers, is it a good practice? 【发布时间】:2017-02-01 19:50:18 【问题描述】:

不确定这是讨论这个问题的最佳场所,因为它有点宽泛,所以我将尝试缩小范围。

我的背景 前几天,我向我最近加入的团队的经理问了几个关于一些设计决策的问题。我正在为一家企业投资银行开发一个交易应用程序,并且有很多遗留代码(就像在任何其他软件应用程序中一样,在变化中存活了 5 年以上)。

简而言之,这里的常见做法似乎是不抛出任何异常并且真正检查传递给方法或构造函数的参数。虽然我同意在某些情况下参数检查毫无价值,但当某些类型或值范围无法与您的方法一起使用时抛出异常可能会有所帮助。

人们在这里使用 TDD,我对此很好,但我认为这种做法并不能阻止一切。但是吞下异常并让其他灾难安静地发生绝不会更好,测试有助于防止这种问题的发生,但并非总是如此。

这始终是一个上下文问题,但在我过去的一项工作中,通过将我们遇到的所有问题冒泡(主要是通过指出传递给某些实体的异常值)来帮助我的团队提高代码质量,啊遗留代码......再次)并进行适当的重构。

问题/场景 假设我有一个类型 B 使用的类型 A,一般来说,在 B 滥用 A 的情况下,在 B 面前抛出 A 的异常(例如值超出范围等),真的吗?不好的做法?它应该帮助 B 以正确的方式处理 A(例如,将正确的参数传递给构造函数等)。当您查看 .NET 框架时,当您滥用类时会出现大量异常,然后引发异常并让您知道它不应该与这个或那个一起工作。

同样,异常应该是异常的,但如果我们举一个解析 IP 地址的非常简单的实体或方法的例子,.NET 框架会温和地让您知道传递的字符串不适合:

var address = IPAddress.Parse(@"It makes sense =]");
// An unhandled exception of type 'System.FormatException' occurred in System.dll
// Additional information: An invalid IP address was specified.

问题 当然,总是有很多上下文需要考虑,而且不是非黑即白,但您认为这是设计 API 以告知开发人员类不能使用此值的好方法吗? (除了文档,如果有的话)而不是例如在它无法工作时返回 null ,什么是最合法的?你怎么知道你是必须抛出异常还是简单地返回 false / null 来表示它不能工作?

【问题讨论】:

【参考方案1】:

只要不符合预期的工作流程,就应该抛出异常。例如,如果使用不正确的参数调用方法(如在您的 sn-p 中),如果外部资源(例如文件)不可用,或者如果应用程序处于不允许该方法运行的状态叫。

一个异常允许其他开发人员决定,一个异常冒出多远才能被优雅地处理。此外,异常提供了有关问题所在的信息。

简单地返回 null 引入了一个问题,即所有返回值在使用之前必须检查是否为 null。否则,您可能会在导致整个应用程序崩溃的地方出现空引用异常。因此,返回 null 应该只用于比抛出异常更例外的情况。

【讨论】:

我同意你的观点,但可惜这对我的经理来说似乎还不够,因为他们一直有很多问题。无论如何,这似乎是答案,至少从我的角度来看。

以上是关于.NET 设计:冒泡异常以更好地重构实体消费者,这是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章

重构此代码以更好地利用 CSharpFunctionalExtensions 库

为啥抛出异常比返回错误代码更好?

如何在我的实体框架和 ASP.NET MVC 项目中重构 connectionString?

选择性地获取核心数据以获得更好的性能(稍后获取大项目)

重构:以Java POI 导出EXCEL为例

是不是“异常”让我的脑子糊涂了?