六边形架构中的逻辑分离


你有没有对你的利益相关者撒谎?我必须承认,我曾经(无意中)做过一次……我画了非常漂亮的方框和箭头,然后将它们呈现给他们,作为他们所负责的软件产品体系结构的“逻辑视图”。但是,那些逻辑箱本来应该是一组具有特定用途的类,但并未在代码中表示。源代码真是一团糟,基本上只是意大利面条代码。到处都有依赖项,没有任何定义的规则或任何体系结构的规则。我的图片和源代码之间有明显的差距。

如果你读过我以前的帖子,编写你的建筑结构,你知道的一个结构,建筑师用句法结构中创建的软件系统。通常,这些构造是包,名称空间或模块。因此,基于这个想法,我们使用“六角体系结构样式”创建了一个应用程序,该样式建议的每个逻辑类组在下面的图片中均表示为一个包。

hexagonal-example.png

当我们使用名称空间或包定义和编写逻辑类组(层,模块,组件等)及其关系时,我们说它们之间存在逻辑分隔。也就是说,其限制由语法元素定义,但是所有类(无论它们属于哪个名称空间)都位于同一物理位置。这意味着我们能够从任何程序包中的任何类引用到任何其他程序包中的任何其他类(在像Java这样的语言中,您具有程序包私有类,但这不足以实现我们想要做的事情)。另外,如上图所示,每个逻辑组都有自己的依赖性。例如,adapters.store程序包依赖于数据库驱动程序实现构件。但是,没有什么可以阻止应用程序包以使用属于数据库驱动程序构件的类。

另一方面,当我们使用以进程间形式(例如,通过HTTPS消息)进行通信的层来定义类组及其关系时,我们会在它们之间施加物理隔离。物理隔离确保遵守基本体系结构规则。仅举几例,具有物理隔离的类组将只能通过其公共接口在它们之间进行通信。此外,某些类组的依赖项(第三方库)将仅对他们可用。

但是我们不想使用层,至少在开始时我们要保持简单。如果必须扩展,则可以选择分层,因此我们必须确保,如果需要的话,将来我们可以在不重写应用程序的情况下到达那里。

那么,有哪些选择呢?我们可以为每个包(一组类)创建一个源代码项目/存储库。并从中产生文物。因此,例如,adapters.store项目将具有application.ports.out工件作为依赖项。这将起作用,并且将确保我们的体系结构规则,但会使事情复杂化。另一个选择是使用ArchUnitjqassistant之类的工具来验证每个提交的依赖性。如果在某些时候不能确保这些体系结构规则,则您的依赖关系将是意大利面条,并且您将无法说明您的六角形样式。更糟糕的是,如果您的应用程序成功并且需要扩展,那么在没有首先解耦类组的情况下将无法进行物理分离。


原文链接:http://codingdict.com