下面是Bobs original blog post的经典Clean Architecture图。
我对网关为何比用例更外向感到困惑。到目前为止,我在所有此类图表中都存在这种情况,其中包括网关或其他某种形式的数据访问机制。
我知道用例不应绑定到数据访问机制的细节,因为它们应隐藏在体系结构边界的后面。同时,构成此边界的服务的唯一用户应该是用例。这与该图有很大的冲突,因为遵循视觉规则,用例不能使用网关(虽然它们需要),而框架式的东西可以使用它们(而不应该)。
我想念什么吗?如果没有,是否有更正确的方法以可视方式表示“清洁建筑”的规则?
我之所以问,是因为我正在创建一个显示“干净架构+ DDD绑定上下文”的图。
我对DB和服务位不在UseCase圈之外感到不满意,因为不清楚用例是有界上下文的公共接口,并且不能从外部直接访问持久性。
类似的事情解决了这两个问题,但引入了一个新问题:没有数据访问层边界的指示。实际上,根据视觉规则,该图表明,有界上下文中的所有内容都可以直接访问持久性。
我认为我遇到了同样的问题,导致网关在原始图中“放错了位置”,并且正在寻找解决方法。
答案 0 :(得分:4)
该图显示了实现所在的位置,而不是接口。网关接口与用例一起存在。
答案 1 :(得分:1)
该图是Alistair Cockburn的Hexagonal Architecture的更详尽的版本,它对适配器的使用(特别是对于CDI而言)更加精确。
从本质上讲,其想法是将依赖关系向内转:用例可能取决于实体(即,导入与域相关的程序包并使用域数据类型; Cockburn并未将它们描述为单独的圆圈,而是描述为“应用程序”)。左侧的适配器可以调用用例(即 execute 或中止它们,例如使用命令模式),而用例则可以调用接口(例如service或仓库外观,由右侧的Adapters实现,使用依赖反转的原理来保留入站方向。
如果您对“左”和“右”感到困惑:在Cockburn的图片中,六边形在左侧(输入/交互机制)和右侧(持久性,外部系统,服务)具有适配器。您可能会认为它是一个旋转了90度的3层架构图,其中域层不依赖于持久层,而是相反。
同样,由于异常的六边形图像,Cockburn的解释也许更难理解,但它是更精确的解释,因为它并没有尝试包括所有内容,而是专注于依赖关系的基本原理。答案 2 :(得分:1)
在您的BC绘图中,您缺少UC之外的环绕圆。这个圆圈是基础结构,您应该在其中放置域模型的Repository接口的Repository实现。该实现使用一种技术(例如SQL)访问数据库。
所以圆圈是从内到外的:
依赖关系指向内部,而不仅仅是内部的下一圈(基础结构取决于应用程序层和域模型)。
虽然我使用六角形结构。
答案 3 :(得分:0)
网关接口必须驻留在用例层中,并在接口适配器层中实现,以确保依赖性规则。
Interface Adapters Layer || Use Cases Layer
||
+-----------------+ || <implements> +-------------+ <uses> +---------+
|JDBCEntityGateway| --------++--------------> +EntityGateway| <------ | UseCase |
+-----------------+ || +-------------+ +---------+
||
此模式可以应用于每个建筑边界。较高层定义了一个接口,以告知需要什么而不是如何完成。较低层实现该接口,从而定义其完成方式。也许这就是为什么该图层被命名为interface adapters
的原因。结果,您可以通过提供另一个实现来更改完成某事的方式。您现在可能已经意识到这就是开闭原则。
但是请记住,接口应该是用例需求的稳定抽象。不要在该界面中放置特定于实现的内容,例如如果您指定类似List<Eintity> find(String where)
的查找方法。因为where
字符串是一个细节,可能是SQL或JPQL字符串部分。您应该引入一个EntityCriteria
来描述选择标准,该实现标准独立于实现。