📜 ⬆️ ⬇️

Layers, Bulbs, Hexogons, Ports and Adapters - it's all about one thing

Mark Seemann's translation of popular software development architectures and what they have in common.

One of my readers asked me:
Vernon, in his book “Implementing DDD,” talks a lot about the Ports and Adapters architecture as a more advanced level of Layered Architecture . I would like to hear your opinion on this matter.
If you do not go into details, then in my book I describe this particular architectural pattern, although I never call it by that name.

TL; DR. If we apply the principle of dependency inversion to a layered architecture, then ultimately we get Ports and Adapters .

Layered Architecture


In the book, I describe typical pitfalls that arise when working with Laminated Architecture . For example, a popular error when building it:
')
image

The arrows show the direction of the dependencies, that is, the User Interface depends on Domain, which in turn depends on Data Access. This is a gross violation of the Principle of Inversion of Dependencies , because Domain depends on Data Access, but
“Abstractions should not depend on details. Details must depend on abstractions. ”
- Agile Principles, Patterns, and Practices in C #
Dependencies in this scheme need to be inverted as follows:

image

The scheme looks almost the same as the previous one, however, it is important to note that the directions of dependencies have changed, and now Data Access depends on Domain, and not vice versa. So, the scheme corresponds to the Principle of Inversion of Dependencies - details (UI, Data Access) depend on abstractions (Domain Model).

Onion Architecture


The previous example is quite simple, as it includes only three components. Let's imagine a more realistic project in which the Principle of Inversion of Dependencies would be observed:

image

Despite the large number of components, all dependencies are directed inside. If you think "layers", you can select and portray them as follows:

image

These layers really resemble onion layers, no wonder Jeffrey Palermo called the architecture Onion Architecture .

The principle of Inversion of Dependencies is still observed, since dependencies go only in one direction. However, it can be noted that the UI (red) and Data Access (blue) components are located in the same layer (I added several yellow components, which, for example, can symbolize unit tests). It seems that somewhere there is a mistake, but in fact everything is correct, because all these components of the outer layer are on the borders of the application. Some borders (UI, APIs) look outward, others (databases, file systems) inwards (operating system, database server).

As you can see from the diagram, components may depend on other components of their layer, but does this mean that UI components can directly access components of Data Access?

Hexagonal Architecture


Despite the fact that the traditional Layered Architecture has experienced the peak of its popularity, this does not mean that all its principles have lost relevance. The idea of ​​allowing UI components to access the Data Acess directly is invalid. Direct interaction between them can cause changes in data to bypass important business logic and break consistency.
You may have noticed that I have grouped the orange, yellow, and blue components into separate groups. This is done so that the UI components do not depend on and do not communicate directly with the Data Access components and vice versa. Let's divide these groups graphically:

image

The result was exactly six sections (three empty). Let it be a good liner to the concept of Alistair Cockburn Hexagonal Architecture ( hex = hex ):

image

You might think that I cheated by creating exactly 6 sections, making the diagram hexagonal, but there is nothing to worry about, because the hex has nothing to do with Hexagonal Architecture ( however, the source explains the connection between these concepts of the translator ). The name of the pattern does not reflect its essence. Therefore, I like to call it Ports and Adapters .

Ports and Adapters


In the diagram above, we see a too deep hierarchy of dependencies. When the diagram consisted of well-defined circles, we had 3 "onion" layers. The hexagonal dependency diagram still has these intermediate (gray) components, but, as I tried to explain earlier, the flat dependency hierarchy is better nested. Let's try to make it as flat as possible inside the hexagon:

image

Components inside a hex have only a few (or no at all) dependencies on each other, whereas components behind a hex work as adapters between internal components and the boundaries of the application - its ports .

Summing up


In my book, I did not invent a name for the architecture I was describing, but in fact it turned out Ports and Adapters . In addition to the options described above, there are other architectures that follow the Principle of Inversion of Dependencies , but the basis of the book “Dependency Injection in .NET” is certainly Ports and Adapters .

I did not use the names Onion Architecture , Ports and Adapters in my book because I did not know about them at that time. But without even realizing it, I described precisely these patterns. Only later, having familiarized myself with them, did I recognize my architecture in them. And this confirms that Ports and Adapters are an example of a real, canonical pattern, because one of the signs of a pattern is that it can manifest itself in various, independent environments and situations, after which it “opens” as a pattern.

Source: https://habr.com/ru/post/344164/


All Articles