当您应该偏离特定原则/架构时,遵循它比不遵循它变得更加不便。这是因为无论我们谈论软件还是实际建筑物,项目需求都会塑造架构。一开始可以尝试让架构适用于每种情况,但这主要是为了让您可以了解它何时不适合特定情况。
不幸的是,我不知道该图像来自何处的完整背景,但从您提到的 SRP 来看,它看起来像是 Bob 叔叔的作品,或者是受到密切启发的东西。我想你可能犯了我和其他几千名开发人员在 SRP 上犯的同样的错误。引用 Clean Architecture(鲍勃叔叔的书):
在所有 SOLID 原则中,单一职责原则
(SRP)可能是最不被理解的。这很可能是因为它有
一个特别不恰当的名字。程序员太容易了
听到这个名字,然后假设它意味着一个模块应该做
一件事。
就上下文而言,模块一词并不意味着 Gradle 模块,Bob 大叔继续将这个词定义为源文件(在 OO 中我们可以将类视为 Controller)。我将让您研究 Bob 叔叔对 SRP 的真正含义,因为我不再使用该术语,也不想解释它。这些都不是对鲍勃叔叔的不尊重。我很喜欢他的作品。
回到这个问题,如果不了解有关控制器的更多上下文,我很难回答(它只是处理点击并将它们转发给适当的交互器吗?)。我假设这是一个 Android 应用程序,在这种情况下,我只需将 Controller 和 Presenter 组合成一个类。在我看来,这既不违反鲍勃叔叔的 SRP(关于分离因不同原因而改变的事物),也不会导致类的内聚度低(这涉及到什么是模块/class/function/source 确实)。我意识到这部分是主观的,但在我看来,处理 UI 交互和为 ViewModel 准备返回的后端数据都适合特定 GUI 功能的表示逻辑的角色。
如果做不到这一点,请忽略我所说的以及图表告诉您的内容,只需查看代码即可。把它们分开真的比分开能解决更多的问题吗?采取相应的行动。
考虑到您提到的要求,我认为没有任何明智的方法可以完全遵循此图,但如果我真的必须将 Controller 和 Presenter 分开,我会这样做:
在控制器和演示者之间使用观察者(发布者 - 订阅者)模式(或者可能是演示者和交互者......不是我会做的,但这张图也没有反映我通常如何使用交互者)。您可以让所有内容保持松散耦合并避免它们之间的具体引用(即绘制箭头)。
你可以有一个 Usecase,它的唯一目的是处理鼠标点击并回调它发生的 Presenter。老实说,这似乎是一个荒谬的解决方案。拥有一个封装了在 UI 中递增计数器的业务逻辑的交互器有什么意义?除非您每次都保存该计数器,否则它甚至不适合从术语业务逻辑开始。
希望对您有所帮助;只是想分享我过去的经验,以防万一。