干净的架构图

时间:2018-08-12 17:10:39

标签: architecture diagram clean-architecture

下面是Bobs original blog post的经典Clean Architecture图。

Clean Architecture

我对网关为何比用例更外向感到困惑。到目前为止,我在所有此类图表中都存在这种情况,其中包括网关或其他某种形式的数据访问机制。

我知道用例不应绑定到数据访问机制的细节,因为它们应隐藏在体系结构边界的后面。同时,构成此边界的服务的唯一用户应该是用例。这与该图有很大的冲突,因为遵循视觉规则,用例不能使用网关(虽然它们需要),而框架式的东西可以使用它们(而不应该)。

我想念什么吗?如果没有,是否有更正确的方法以可视方式表示“清洁建筑”的规则?

我之所以问,是因为我正在创建一个显示“干净架构+ DDD绑定上下文”的图。

enter image description here

我对DB和服务位不在UseCase圈之外感到不满意,因为不清楚用例是有界上下文的公共接口,并且不能从外部直接访问持久性。

类似的事情解决了这两个问题,但引入了一个新问题:没有数据访问层边界的指示。实际上,根据视觉规则,该图表明,有界上下文中的所有内容都可以直接访问持久性。

enter image description here

我认为我遇到了同样的问题,导致网关在原始图中“放错了位置”,并且正在寻找解决方法。

4 个答案:

答案 0 :(得分:4)

该图显示了实现所在的位置,而不是接口。网关接口与用例一起存在。

答案 1 :(得分:1)

该图是Alistair Cockburn的Hexagonal Architecture的更详尽的版本,它对适配器的使用(特别是对于CDI而言)更加精确。

从本质上讲,其想法是将依赖关系向内转:用例可能取决于实体(即,导入与域相关的程序包并使用域数据类型; Cockburn并未将它们描述为单独的圆圈,而是描述为“应用程序”)。左侧的适配器可以调用用例(即 execute 或中止它们,例如使用命令模式),而用例则可以调用接口(例如service或仓库外观,由右侧的Adapters实现,使用依赖反转的原理来保留入站方向。

如果您对“左”和“右”感到困惑:在Cockburn的图片中,六边形在左侧(输入/交互机制)和右侧(持久性,外部系统,服务)具有适配器。您可能会认为它是一个旋转了90度的3层架构图,其中域层不依赖于持久层,而是相反。

同样,由于异常的六边形图像,Cockburn的解释也许更难理解,但它是更精确的解释,因为它并没有尝试包括所有内容,而是专注于依赖关系的基本原理。

答案 2 :(得分:1)

在您的BC绘图中,您缺少UC之外的环绕圆。这个圆圈是基础结构,您应该在其中放置域模型的Repository接口的Repository实现。该实现使用一种技术(例如SQL)访问数据库。

所以圆圈是从内到外的:

  • 域模型(实体,值对象,存储库(接口)等)
  • 应用层(用例)。
  • 基础结构(UI,存储库(实现)等)

依赖关系指向内部,而不仅仅是内部的下一圈(基础结构取决于应用程序层和域模型)。

虽然我使用六角形结构。

答案 3 :(得分:0)

网关接口必须驻留在用例层中,并在接口适配器层中实现,以确保依赖性规则。

  Interface Adapters Layer    || Use Cases Layer
                              ||
  +-----------------+         || <implements>    +-------------+   <uses>  +---------+
  |JDBCEntityGateway| --------++-------------->  +EntityGateway|  <------  | UseCase |
  +-----------------+         ||                 +-------------+           +---------+
                              ||

此模式可以应用于每个建筑边界。较高层定义了一个接口,以告知需要什么而不是如何完成。较低层实现该接口,从而定义其完成方式。也许这就是为什么该图层被命名为interface adapters的原因。结果,您可以通过提供另一个实现来更改完成某事的方式。您现在可能已经意识到这就是开闭原则。

但是请记住,接口应该是用例需求的稳定抽象。不要在该界面中放置特定于实现的内容,例如如果您指定类似List<Eintity> find(String where)的查找方法。因为where字符串是一个细节,可能是SQL或JPQL字符串部分。您应该引入一个EntityCriteria来描述选择标准,该实现标准独立于实现。