当枚举具有超能力时(迅捷)

在Mimo,我们每周举行一次Show&Tell会议,每个团队介绍他们上周所做的工作,之后,您可以分享您最近学到的东西或您热衷的东西。 我在Mimo讨论了“枚举何时具有超能力”之后,创建了以下文章,因为我想这可能会让更多开发人员感兴趣。 这是Swift版本。 您还可以在这里找到这篇文章的Kotlin版本。

假设我们有一个用Swift编写的iOS应用,现在我们想添加一个用户登录名。 我们使用4个参数创建一个简单的登录功能。 usernamepasswordsuccess callbackfailure callback

到目前为止,一切都很好。 我们还假设我们已经提前计划了。 对于在登录时遇到错误的情况,我们创建了一个IncorrectPasswordError类来处理故障回调中的此特定错误。

我们的解决方案有效。 我们可以添加诸如TimeoutErrorUsernameNotFoundError类的更具体的错误,并在我们的失败回调中对其做出反应。 那么,如果它起作用了,我们为什么还要改变它呢? 🤔

  • 我们依靠类型转换来处理特定的错误。
  • 我们将所有AuthenticationErrors与可能发生的任何其他RuntimeError混合在一起
  • 很难发现不同的错误。

如果您知道自己在做什么,则类型转换可能不是问题,但其他两点仍然成立。 在登录过程中,我们基本上会在登录流程中遇到一些错误,例如用户输入了错误的密码/电子邮件或发生了超时。 与可能发生的任何其他意外错误不同 ,对此类错误的处理方式不同 ,因此也许应将它们分开处理。

第二大问题是可发现性 。 如果不查看确切的实现,我们不知道我们需要处理哪种错误。 编译器在这里也无济于事。 那么我们如何做得更好?

Swift具有强大的功能( 带有关联值的枚举),其中枚举可以容纳更大的数据块。 我们将使用它来重构我们的登录流程。

我们首先对所有可能发生的情况以及我们要专门处理的情况进行建模。

  • successsuccess登录将包含user对象。
  • usernameNotFound找不到usernameNotFound
  • incorrectPassword错误的密码
  • timeout
  • unexpectedError —任何其他意外错误。 现在将这些错误与其余错误分开

现在,我们新的登录功能只有一个带有LoginResult回调。 为了处理不同的结果,我们创建了一个简单的开关盒

首先,我们现在将登录流程错误与任何其他意外错误分开了。 这些意外错误在单个case块中一起处理,而其他usernameNotFoundusernameNotFoundincorrectPassword具有自己的case块。 我们改进的第二件事是可发现性。 查看LoginResult枚举,我们可以确切地看到可能发生的事情以及应该处理的事情。 我们不再需要知道login功能的内部实现。 该解决方案的另一个很酷的方面是传递数据,这仅对特定枚举情况很重要。 只有在.success ,我们才能在结果中获得一个用户对象。 添加另一种情况也很容易。

使用枚举的最大好处是清晰的API和可发现性 。 使用我们的登录功能的任何开发人员都将立即知道会发生什么。 哪些错误是登录流程的特定部分,需要进行处理。 在很多情况下,我们可以使我们的API更清晰,更易于使用。 具有高级值的枚举可以有很大帮助。 因此,请尝试一下。