【问题标题】:Clean Architecture: Sequence Flow Among Frameworks清洁架构:框架之间的序列流
【发布时间】:2017-05-24 01:02:53
【问题描述】:

我一直在尝试从博客、文章和视频中了解有关 Bob 叔叔的清洁架构的更多信息。

如果我要在此架构中使用数据库,那么 UI(作为 Web 或表单等框架)应该了解数据库的哪些信息?或者更一般地说,数据应该如何在同一层中的两个或多个片段/部分之间流动?

例如,UI 将与我的适配器/网关对话以与业务实体进行交互。对于读/写,我可以看到 UI 可以调用可以访问数据库并传入适配器/网关的任何类/类,以便它可以与业务实体交互。

    public class SomeUI
    {
        public static void Main(string[] args)
        {
            SomeAdapter adapter = new SomeAdapter();
            SomeDataAccess db = new SomeDataAccess();
            db.Save(adapter);
        }
    }

    public class SomeDataAccess
    {
        public void Save(SomeAdapter adapter)
        {
            //Interact with database
        }
    }

    public class SomeAdapter
    {
        //properties
    }

许多文章与这篇文章几乎没有什么不同 (https://subvisual.co/blog/posts/20-clean-architecture)。我还没有找到一篇很好的文章来介绍同一层中的各个部分应该如何相互协作。因此,提及该内容的文章将是一个可以接受的答案。

这似乎没有违反依赖规则,但感觉好像我做的不对,因为我在我的 UI 和数据库之间建立了依赖关系。我相信我可能过度思考了这个概念,并且我相信这可能来自于学习三层架构(UI -> BLL -> DAL)。

【问题讨论】:

    标签: database user-interface frameworks clean-architecture


    【解决方案1】:

    你问:

    如果我要在此架构中使用数据库,那么 UI(作为 Web 或表单等框架)应该了解数据库的哪些信息?或者更一般地说,数据应该如何在同一层中的两个或多个片段/部分之间流动?

    Clean Architecture中没有UI组件这样的术语。在简洁架构术语中,UI 将是表示层交付机制,分解为以下组件:

    • view model 生成器(或 presenter 使用 Uncle Bob 的术语),负责封装 UI 的业务规则。这应该访问业务模型以便从中生成视图模型。业务模型由其调用者 interactor 传递给 interactor response 对象内的 presenter 方法。
    • 视图模型保存视图的数据并通过例如事件间接传递给视图
    • 现在与域模型和所有层分离的哑视图显示视图模型的数据。

    以这种方式分解可确保更好的可测试性、更好的 SRP 以及与应用程序、域和基础架构层的更多解耦。

    因此,您的表示层应该对基础设施层一无所知。


    也许您对使用某种 Web 表单 组件/库的示例感到困惑?这种组件提出了与多个架构层相关的相互关联的功能:域、应用程序和表示......因此 Web 表单 组件特别适合在 Clean Architecture 中令人满意地适应。由于这种不灵活,我仍在努力找出在我的 Clean Architecture 实现中集成 Web 表单 组件的最佳方式...


    最后,为了清楚起见,你说:

    例如,UI 将与我的适配器/网关对话以与业务实体进行交互。对于读/写,我可以看到 UI 可以调用任何可以访问数据库并传入适配器/网关的类/类,以便它可以与业务实体交互。

    UI 不负责与您的实体进行交互,但顾名思义,这是 interactor 的责任(interactor = 用例)。 Interactor是用来封装应用业务规则的,它们代表应用层。他们可以通过 Entity Gateway 对您的实体进行 CRUD,这是您到基础设施层的适配器,可以是 ORM、REST API 或其他任何东西......


    编辑#1

    由于这里有一千个字的图片是 Bob 大叔的 UML 类图,表示清洁架构的结构(以及相关组件之间的数据流)


    编辑#2

    在我看来,您对清洁架构中控制流的表示有点颠倒了。参考上图和鲍勃大叔的比喻:

    如果您不希望您的代码依赖于某个事物,请将这个事物设为插件

    (换句话说,让那个东西成为你想要独立于它的代码的客户端。)

    简洁架构中,您需要表示层,或者更具体地讲,需要交付机制 (Controller + Presenter + ViewModel + @987654327 @) 成为您业务层的插件(由通信通道边界右侧的组件组成)。

    【讨论】:

    • 就我使用 UI 的地方而言,我越来越意识到我倾向于交替使用 UI 和表示层。对于 UI 责任部分,我的意思是与将与交互者通信的某些网关通信。对于我的整个问题,我同意我的观点来自大多数示例中显示的“框架”环中的“某些 Web 表单”。仍然让我感到困惑的概念是,依赖方向是否/如何不强制数据流方向,我不确定这是否只是我自己的过度思考。
    • 不确定我是否理解您所说的仍然让我感到困惑的概念是,依赖方向是否/如何不强制数据流方向。看看我的编辑,这可能会帮助你看得更清楚?如果没有,请告诉我。
    • 在我的脑海中(基于图片),我一直看到分隔表示层的线与“实体网关实现”显示的分隔线相同,对于这种情况,我很难了解表示层如何调用模型或定义的任何边界对象以请求/读取要显示的数据,然后模型调用交互器(执行用例),然后检索数据。如果交互者没有直接引用/调用实现或接口,什么会执行/调用/传递“实体网关实现”?
    • @eparham7861 当然,您的交互器必须具有对实体网关的引用(您在哪里看到它不应该?)。交互器将使用很可能在交互器实例化期间注入的实体网关。请参阅我的编辑 #2,如果我仍然不明白您的问题,请告诉我...
    • 我想我明白你在说什么。我主要看过图表(例如从这里blog.cleancoder.com/uncle-bob/2012/08/13/…),其中所有网关/演示者/等。位于交互器之上的一层。我认为这意味着网关将对交互器具有引用/依赖关系,而交互器不能对其他网关具有引用/依赖关系,基本上内层不能对上层/外层具有引用/依赖关系。我确实认为您是正确的,因为我正在向后看。
    【解决方案2】:

    我一直在对其他清洁架构示例进行更多研究。

    (source)。

    从上图中,看起来 App(业务实体和用例)与 Delivery(Externals:UI)来回对话。 Delivery 用于与外部(外部:DAL)对话。

    交付是您实现应用程序本身的交付机制的地方。交付是您的应用程序与外部数据源集成并显示给用户的地方。这意味着最简单的 UI,但也意味着创建外部对象的具体版本,例如数据插孔,以及调用应用程序本身的操作。 -复古摩卡

    所以,这让我相信,是的,顶部的代码示例是有效的,但我仍然愿意听取其他人是否有更多关于答案的信息。

    【讨论】:

      猜你喜欢
      • 2014-06-22
      • 2021-06-17
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 2019-04-17
      • 1970-01-01
      相关资源
      最近更新 更多