我在天真的建模者中看到的一个常见的误解是他们的模型不会失败----他们认为他们处理可能出现的异常。实际情况是,不管您认为您在模型中管理异常的程度如何,失败都会发生。模型的规模越大,组件失败的可能性就越大。磁盘失败,内存失败,网络组建的失败,还有其他基础设施的失败---简而言之,失败会发生在你完全无法控制的情况下。

针对失败而设计。在开发包含许多协作组件的大型服务时,这是一个核心概念。这些组件将会失败,并且会经常失败。这些组件并不总是相互协作和失败。一旦服务扩展到超过10,000台服务器和50,000个磁盘,故障将会在一天内多次出现。

-----James Hamilton

确实。响应性模型的一个主要教诲就是围绕失败进行设计,并提高模型的整体弹性。在表1.4提到了对失败的可响应性;只有当您的模型有能力处理来自您的应用程序内部的故障,以及来自其他外部源的故障时,才能实现这一点。这并不意味着让您使用大量的异常处理逻辑来污染您的领域模型。基本的思想是接受失败是必然发生的,并实现策略来明确地处理它们,就像它们发生在您的系统的不同部分一样。

考虑一个例子:假设一个用户要求计算她在银行的各种账户的证券投资组合(我觉得的应该是表达基金的意思)。在计算过程中,其中一个步骤失败,可能是因为持有某一特定帐户的余额的服务器是不可访问的。你应该如何处理你程序中的这种失败?至少有两种解决方案:

  • 尝试在计算投证券资组合的应用程序代码中包含异常处理逻辑。但是对于任何访问后端服务器的api,都可能发生这种情况!想象一下在所有这些地方复制相同的代码来进行异常处理。其结果是一场软件工程灾难-----我们称之为处理separation of concerns(分离关注点)的失败版本。我们将领域逻辑与异常处理代码合并在一起,最终导致后者污染了前者。显然这并不可取。

  • 有一个独立的模块来处理故障。所有的失败都被委托给这个模块,这个模块负责根据用户定义的策略来处理它们。这种方法使您的域模型保持干净,并从业务逻辑中分离出故障处理。

图1.11总结了这两种方法.

您一定在想,如果所有的故障都是通过一个模块处理的,那么这是否会成为整个模型的可伸缩性瓶颈?如何确保失败处理与处理其他域逻辑的其他模块一样具有可伸缩性?

答1.8:我确定你回答的是正确的。它就是缺乏随着负载的增长而保持可响应的能力----这意味着不要随着负载的增加而扩大规模。因此,它违反了可伸缩性标准。

解决方案在于故障处理模块本身的设计。这并不是说您必须在整个应用程序中都有一个用于故障处理的单一模块。其思想是要有集中的处理程序。处理程序的数量将取决于应用程序的整体模块性。在前面的例子中,您可能有一个模块来处理投资组合计算的所有失败。

PS:图1.11英文翻译

在域模型中处理失败的策略。为处理故障设计一个单独的模块(几乎)总是一个更好的选择。

results matching ""

    No results matching ""