清洁架构中的混淆术语交互器

Confusing term Interactors in Clean Architecture

按照干净的架构,设计交互器是包含所有业务逻辑的部分。交互器这个词让我很困惑。在我看来,Interactor 喜欢在数据和演示者等两个不同层之间进行交互。

这个词用得对吗? 任何人都可以清除 Interactor 的目的吗?它遵循哪种模式? 如果 Interactor 不是我看来的那样,那么设计模式是什么 层层交互?

据我所知,它相当于模型视图展示器 (MVP) 架构中的展示器。

它执行业务逻辑,不存储或显示数据。它创建一个单独的层,独立于数据存储或显示的方式或位置。它只关心任何格式的输入和输出。它可以与 Observer、Adapter 和 Façade 模式组合使用,作为回调接口、代码的通用扩展点以及任何非 UI 或数据存储用途的解耦入口点,分别。

我假设它被称为交互器,因为视图与它交互以计算值并刷新任何显示的 UI 元素,并且它与模型对象交互以提取数据。它还可以与数据库交互以进行 CRUD 操作,但我认为这主要是在存储库模式中解决的,因为这不是真正的业务逻辑。

这是MVP模式。是的,正如您所说,它是演示者和数据之间的中介(作为休息呼叫或共享偏好或 Sqlite 的一种形式)。

交互器是一种与"business logic"概念无关的设计模式。在不深入细节的情况下,交互器模式是命令模式的扩展;每个 "business logic" 对象都被视为一个 "black box",一个为客户端执行的简单指令,将调用操作的对象与知道如何执行操作的对象分离。 (详见参考书目)。

在 android 环境中有一个简单的 'rule' 要求程序员在后台线程中执行长时间耗时的任务,因此交互器模式扩展了 "Command pattern" 添加一层螺纹。所有这些复杂的东西都是为了创建一个 "clean architecture" 而实现的,它需要一个可扩展、可维护且(可以说)可理解的代码。

关于问题.. 层与层交互的设计模式是什么?它可能有不止一个正确答案,视情况而定。你可以使用一个简单的接口作为入口点,这样你就可以使用适配器模式,或者可能是外观模式,或者如果你想做一些更高级的事情,你可以实现一个事件总线系统。

来源: 设计模式简单解释 - 作者 Alexander Shvets。第 14 页(适配器)、第 32 页(命令)、第 47 页(外观)

交互器为各种用例提供​​实现。理想情况下,每个用例应该有一个交互器,但它可能会根据您的应用程序的规模而有所不同。

现在,为什么它对每个应用程序都没有意义?假设您有两个应用程序。在第一个应用程序中,您只需要读取一个用户。在另一个应用程序中,您只需更新同一个用户。您将有两个不同的交互器,如 GetUserInteractor 和 UpdateUserInteractor。如果您考虑一下,UpdateUserInteractor 会让第一个应用程序 no 有意义(反之亦然),对吧?但是两个应用程序的 business/domain 逻辑仍然可以相同,其中包括两个服务(读取和更新)的实现,例如,在相关的 business/domain 对象中(或作为单独的用例对象) ).这些对象显然封装了与应用程序无关的业务规则,因为它们可以插入两个或多个不同的应用程序下。

应用程序和用户之间发生的通信通常是特定于应用程序的。正如其他人已经提到的,您可以让交互器对用户操作执行命令。或者你可以选择另一种类似的方式。但是命令模式确实很方便,可以说使整个代码更加一致、统一、易于理解。

最后但同样重要的是,交互器的另一个重要方面是 'boundary interfaces',即 多态性 为输入和输出交付部署的 类。

(PS:例如,在 Android 中,使用新的架构组件,Fragment/Activity 可以被认为是输入边界的实现,因为您将输入事件传递到您的业​​务逻辑(或域模型)- 它是控制器。LiveData 更像是输出边界实现,因为它在引擎盖下使用观察者模式并通过交互器将数据传送回 UI。在这种情况下,我认为这使得 ViewModel 成为交互器的有力候选者,因为它接收输入事件(以及与这些事件对应的命令)并且还包含要观察的 LiveData 实例。所有这些解耦是否很好,或者多态部署?好吧,这是主要与您的设计有关。对于协程,现在似乎没有必要 callbacks/listeners - 所以这张图片的另一个维度。)

这是我的看法。我希望这很清楚。

在干净的架构方法中,用例交互器是表达特定业务规则的层。用例交互器与实体(不可知的业务规则)交互以实现用例意图。实体可以在另一个应用程序中使用,一旦它们是不可知的,另一方面,用例交互器是特定的应用程序对象。

可以在 Robert C. Martin 的 Clean Architecture 一书的第 20 章中找到

如果您熟悉领域驱动设计,那么可以将 Interactor 与应用程序服务进行比较。此外,说“按照干净的架构,设计交互器是包含所有业务逻辑的部分是不正确的。”相反,Entities 会包含业务(与应用程序无关)逻辑;而 Interactors 将包含特定于应用程序的逻辑。 Interactors 会调用 Entities 来完成用例,其中用例可能类似于创建采购订单。

回到 Robert Martin(Bob 叔叔)在他的培训视频 Architecture, Use Cases, and High Level Design 中使用的清洁架构术语,Bob 叔叔说了以下内容:

Interactors are application-specific. That means that any application specific business rule belongs inside an interactor. The interactors achieve their goals with application-specific logic that calls the application-agnostic logic within the entities. For example, the CreateOrderInteractor invokes both the constructor and the GetId method of the OrderEntity. Clearly, these two methods are application-agnostic. It's the interactor that knows how to call those two methods to achieve the goal of the use case.

根据您的观察,Interactor 似乎在两个不同的层(如数据和演示者)之间进行交互,该工作实际上属于 BoundaryBoundary 位于交付机制和 Interactor 之间,其中交付机制可能是桌面应用程序、MVC 应用程序、API 等。这使实际应用程序和业务代码保持分离并且可从一种交付机制转移到另一种交付机制。

他还在附加部分中提供了一张漂亮的图表,显示了您购买视频后的互动情况。它看起来像下面这样:

Delivery Mechanism ==> Boundary ==> Interactor ==> Entity

P.S。上面引用的视频非常有趣和信息丰富。