los*_*ost 28 architecture hexagonal-architecture
在阅读了有关Ports和Adapters架构的不同来源(包括Alistair Cockburn的原始文章)后,我仍然不确定术语"端口"和"适配器"的确切含义 - 特别是在将这些概念映射到实现工件时.
几个来源(例如这篇文章)暗示这种体系结构模式中的端口是外部的工件,其次是中间层中的适配器,它们在端口和处于核心的应用程序之间进行转换.
但是,在Cockburn的原始文章中,端口出现在适配器层的外部和内部,具体取决于通信方向:
实际上对我来说,"全部外部"方法和"内部和外部"方法都没有意义 - 我会将端口看作始终放在应用程序旁边的工件,而不管通信方向如何.Imo这也与端口和适配器的比喻一致:E.g.有一个带有串行端口的设备,要连接另一台没有串口的设备,我需要一个适配器,从我的设备的角度来调整入站和出站通信.
来到这个体系结构的实现,我会看到端口的定义,而不是作为我的应用程序的一部分,我会看到不同的适配器是我的应用程序的"外部".E. g.单个端口的实现可以包括facade(由适配器调用以进行入站通信)和interface(由适配器实现用于出站通信).
术语端口和适配器的正确含义是什么?如何将这些概念映射到实现工件?
更新:
发现这篇文章类似于我的理解.如果存在某种共同协议,问题仍然存在.
Vla*_*ler 22
inf3rno给出了一个很好的答案,澄清了原始问题,但强调端口和适配器的一些其他用途可能是有用的.
根据我的理解,端口是您的界面的表达.
港口:
适配器:
端口应接受适配器并确保适配器实现接口.然后它应该只在适配器上调用适当的方法/函数.
该端口应包含在通信测试中.在这种情况下,"模拟"的是两个相邻六边形(或六边形和服务)的核心,并测试端口/适配器/适配器/端口组件.
有关更多信息,您可以查看James Gardner和我在2014年7月伦敦Skillsmatter Microservices 聚会上所提供的六角形微服务的讨论.
inf*_*rno 17
我认为这是非常简单的概念.你有应用程序核心,它不依赖于它之外的任何东西.例如,它不依赖于HTTP框架,数据库驱动程序,邮件框架等等......根据您的问题域,此核心具有非常特定的接口,因此只有在您的问题域发生更改时,应用程序核心的代码才会更改.
例如,您有博客文章,并且您想要为它们添加类别.因此,类别应该流经整个系统,从HTTP通信到数据库通过写入,反之亦然.
现在,如果你想用MongoDB替换MySQL数据库,那该怎么办呢?它不应该影响核心,因为应用程序仍然完全相同:它存储您的博客帖子和ofc.他们的类别并按需返回.所以你需要的只是这种情况下的MondogDB适配器,你可以使用它而不是你的MySQL适配器.
如果您想要一个REST API,而不仅仅是一个简单的HTML页面,该怎么办?它仍然不会影响您的应用程序核心,因此您需要的是另一个用于REST通信的适配器.
因此,在我看来,您的适配器应该具有在应用程序核心中定义的特定接口,并且端口应该使用这些适配器与应用程序核心通信.所以在我看来,端口不必作为类,只是适配器及其接口存在.这个概念很有意义,因为您的应用程序核心不会紧密耦合到您想要使用的端口,而只是紧跟您定义的适配器接口.(顺便提一下,有许多相似的架构.就像干净的架构,洋葱架构,它使用相同的概念和不同的词汇.)
我工作的人在这个架构上做了很好的内部演示.最后,在提问期间,另一位同事问道:
这不仅仅是一个具有不同名称和不同名称的分层架构吗?
而且,说实话,这在很大程度上是正确的.对于许多应用程序,六边形体系结构的结构与分层体系结构相同,只有一些具体细节:
你可以看到,即使做了所有这些事情,它仍然只是一个分层的架构,只是层之间的界限非常严格,而且关注中心层.
因此,要专门回答这个问题,您可以通过识别端口是进出核心的接口来理解端口和适配器,而适配器只是不是核心的实现层.