软件开发中如何将用例与视图分离?

rah*_*aha 4 use-case clean-architecture

我很难理解如何实际实现干净的架构,

请注意以下有关干净架构的要点。

在此输入图像描述

  • 内圈不应该知道外圈
  • 用例不应该了解网络/框架
  • 用例不应该知道视图

传统上,在开发任何反应或任何其他应用程序时。主要焦点是“视图”,因此视图定义用例,用例定义实体。因此,最终结果是用例与视图紧密耦合。

所以当用户与UI交互时,控件从视图开始,视图调用用例,用例使用实体并将结果返回给视图。

这样,就很难将用例和视图分开。

我们如何实现视图与用例的分离?以及从控制器到用例再到视图的控制流。

问题

从上图可以清楚地看出,控制器通过输入端口接口调用uncase交互器。并且用例使用输出端口更新了 UI。

所以,假设我们有如下实体。

{ x : "data x", y : "data y", z : "data z"}
Run Code Online (Sandbox Code Playgroud)

输出将显示在 CLI 或 WEB 中。

op() 假设执行后有一些用例操作,op()结果将显示给用户。

但是,如果 UI 是 WEB,则应该显示x数据。y

如果 UI 是 CLI,则应z显示数据 和 。

我们如何分配逻辑来实现干净的架构?

一种解决方案是,我们可以有输出端口接口。

interface Presenter
{
   public void presentForWeb({ x : "data x", y : "data y" });
   public void presentForCli({ z : "data z" });
}
Run Code Online (Sandbox Code Playgroud)

但这违反了架构。从用例开始,他们应该了解 UI 以便能够正确显示数据。

另一种解决方案是,将输出端口设置为

interface Presenter
{
   public void present({ x : "data x", y : "data y", z : "data z"  });
}
Run Code Online (Sandbox Code Playgroud)

这几乎是一个很好的解决方案,但是我们传递了一些冗余数据。那么如果 z 数据很大,我们只需要在使用 CLI 时传递它即可。

有没有更好的解决方案来实现干净的架构?

pla*_*ist 8

在清洁架构中,“用例”(或“用例交互器”)是指包含业务规则/业务逻辑的类/组件。依赖关系规则定义用例(业务逻辑)不应具有(编译)对视图、任何外部框架或 IO 的依赖关系。

这种架构的好处之一是所有业务逻辑都可以轻松地独立于任何外部依赖项进行测试。

另一个好处是可以替换具体的外部服务或具体的(UI)技术,而不影响软件系统的核心——业务逻辑。

正如您在图片右下角所看到的,控制流仍然从视图到控制器到用例(业务逻辑),然后返回到演示者,然后返回到视图。用例定义的输入和输出端口通过仍然避免(编译)从业务逻辑到控制器/呈现器/视图的依赖关系来允许此控制流。

您可以在我的博客上找到有关业务逻辑如何保持独立于视图的更详细讨论:http://www.plainionist.net/Implementing-Clean-Architecture-Controller-Presenter/