Java中一致的错误传播和处理

每个应用程序都生活在现实世界中,而现实世界并不完美。因此,即使是理想的,无错误的应用程序也注定会不时地处理错误。

自从第一个计算机程序诞生以来,问题就一直存在,软件工程师发明了许多错误处理方法!

Java传统上使用以下方法向调用者发出信号,指出存在错误:

  • 返回一个特殊值(通常,为此目的使用“ null”值)
  • 引发异常

这两种方法都有明显的缺点。

返回一个特殊值将丢弃有关错误实际原因的信息,并通过附加检查使代码膨胀。

与正常的执行流程相比,异常的代价非常高,并且使流程难以遵循且难以验证其正确性。一些库和框架倾向于滥用异常,以使其成为正常执行流程的一部分,这是很疯狂的。

因此,有没有其他方法可以通知呼叫者有关错误而又没有上述缺点?是! 函数式编程提供了一种。

请注意,在下文中,我将尽量避免使用FP专用术语。这不会降低方法的功能性,但是可以为那些还不习惯FP lang语的人简化概念。

Either<L, R>集装箱

这个想法是使用容器作为返回值,而不是普通值。容器很特殊:虽然被声明为两种类型,但实际上在第一或第二种类型中,每次仅保存一个值。

Either<L, R>是通用的容器,不依赖于误差传播/处理。当将其用于错误传播时,按照约定,第一种(或“左”)类型用于表示错误类型,而第二种(或“右”)类型表示返回值类型。

在代码中,这看起来像:

实际上,与通常的“做某事并成功返回结果,如果有错误则抛出异常”并没有什么不同。

更深入的外观具有很多优点:

  • 不再需要返回一些“特殊”值。
  • 有关该错误的信息仍然可用。
  • 执行流程没有中断。

上面的代码演示了“生产”方面。现在,让我们看一下“消费”方面的样子:

此可疑简单代码包含处理错误所需的一切:

  • 如果任何处理步骤返回错误,它将返回正确的错误结果。
  • 一旦发生错误,它将立即停止处理。
  • 它不会中断执行流程,  return语句将始终执行,并且始终将值返回给调用方。
  • 它强制执行“处理错误或传播错误”策略,从而产生健壮的代码。
  • 这种方法的一致应用会产生清晰易读的代码。

专门研究狭窄的用例

可能会注意到,plain Either<L, R>用于错误处理时非常冗长。

首先,它要求明确引用错误类型。尽管通常错误的基本类型并不多。例如,Java使用单一Throwable类型作为所有错误和异常的基类。

冗长和不便的第二个来源(出于此特定目的)是Either<L, R>一般意义上的意义,即它可以用于任何类型,并且其API在双方方面都是对称的。当Either<L, R>用于错误处理时,这要求某些约定的一致应用,例如上面提到的约定。

因此,对于狭义的错误处理,Either<L, R>可以将其专门化为Result<T>类型,该类型假定单个通用的错误基本类型,并已针对错误处理调整了API。这使代码不再那么冗长,也更容易发生意外错误。

使用Result<T>,上面的代码可以重写为以下代码:

现在,代码不再那么冗长,而上面提到的所有属性仍然存在。

修改现有代码以供使用 Result<T>

使用的Result<T>是在自己的代码方便,但我们生活在Java库和框架,不使用它的世界。他们抛出异常并返回空值。因此,我们需要一种方便的方法来与现有代码进行交互。

为此,Reactive Toolbox Core中的  Result<T>实现提供了一组帮助程序方法,该方法允许将传统方法包装到返回Result的方法中。

下面的示例显示如何使用这些辅助方法:

收尾:

本文试图描述Reactive Toolbox Core库的一些主要概念  。当然,这些概念都不是新概念。我只是试图创建一个库,以方便,一致地应用这些概念。

我经常看到整篇关于“ Java太老了,应该退休并用现代语言代替”的文章。上面提到的概念表明,事实并非如此。在现有的Java功能中,可以编写现代,干净且可靠的代码。改变习惯和方法,而不是语言,一切都是必要的。有趣的是,由于适用于一种以上语言的方法,变更方法比变更语言要付出更多的代价。

有什么问题可以加下qq:2062583349。也可添加vx:admindesire,有java、python、web等习资料和视频课程干货”。欢迎交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值