Tech Talk: „Hexagonal Architecture“ mit Thomas Wimmer von netcetera

Tech Talk: „Hexagonal Architecture“ mit Thomas Wimmer von netcetera

Hello everyone, my name is Thomas Wimmer. I'm working as a software architect netcetera here in Linz and in the next 10 minutes I will introduce you to an architectural pattern called hexagonal architecture.

Before jumping directly into the principles behind hexagonal architecture, let's revisit uncommon architectural pattern probably every software developer knows about namely the layout or interior architecture. The main idea behind this architectural pattern is that you divide your software system into a number of layers whereby each of these layers represents a certain technical aspect. As an example when you as a developer are working on some UI components you shouldn't be concerned about whether data you´re currently displaying is coming from or how it is assembled.

What we see in practice is that for a complex system those three layers are usually not sufficient. So what you do is that you divide your software system into a bunch of more layers, thereby each of the upper layers delegates some part of its work to a lower layers. Thereby every layer follows the rule that it can only talk to the direct lower layer.

So this was a quick refresher of layout architecture - let's look on hexagonal ports and adapters architecture. The main idea behind this architectural pattern is that you divide your software system into an inside and outside world. Thereby the application core in the inside interacts with some outside components over so-called ports. Thereby the actual interaction with the outside components happens over so-called adapters. Quite easy so far, right. So let's look at it a little bit closer by following the control flow of a usual user interaction. If some use of our system wants our system to do something he calls the UI adapter. So therefore the adapters which drive our application telling our application to do something I called driving our primary adapters. In order that the UI adapter can do something with the application core, the application core offers some input ports. This imports accept some comments and queries to be executed towards our system. Now that the comment is executed towards our system the application core is doing its business logic, some business rule violation validation, maybe even some complex calculation. And in order to fulfill its business he might need to interact with some external system. So therefore he calls so-called output ports to download the external system and this interaction on the output ports are then interacting with the adapters which do the actual integration towards the external system and this adapters are then called driver driven or secondary adapters. So now that we refreshed all the principles behind layered and hexagonal architecture you might be wondering what is the essential difference between them? In order to figure that out? We will compare the visual representation of this two architectural styles.

But the visual representation which I usually use to describe the architectural patterns, namely this one here, do not allow a fair comparison. So let's deflate the representation of the hexagonal architecture to allow a better visual comparison. If we closely look on this difference here we will see that beside the naming of things and the ports we encounter that some arrows are pointing in different direction. We see that the dependencies between the business logic and the data layer of the layered architecture are pointing in the opposite direction then the application core and the data adapters of the hexagonal architecture. Or phrasing it differently: in the hexagonal architecture, all dependencies of the outer layers pointing towards the application core.

Let's analyze what are the implications of this difference by recalling some solid software design principles. You probably remember the single responsibility principle. It states that a class should have only one reason to change but apply to higher software architecture level we could also say a component should have only one reason to change. Or phrasing it differently: when you change one component of your system you don't want that another component of your system is affected by this change.

So let's look at that example: when you change the data layer in a layered architecture this change might be reflected in the business logic because of the dependency, right? And then if you change the business logic this change might be reflected in the UI because of changes in business logic and the dependency. If you think about it for a second you will notice that in a layered architecture the upper layers have always more reasons to change than the lower layers. So the idea behind hexagonal architecture is that changes in the adaptor do not affect the core and vice versa.

Robert C. Martin who introduced those principles describes this to a new principal in his recent book called Clean Architecture. He states that you should get together those things that change at the same times and for the same reasons. And that you should separate those things that change at different times or for different reasons. He calls this the common closure principle and in fact this is the single responsibility principle applied on a higher software architecture level.

Another important principle, which is applied by hexagonal architecture, is the dependancy inversion principle. It consists of two rules. The first rule states that high level modules should not depend on low level modules but both should depend on abstractions.

So what are the high level models here? The high level models, for example in our layout architecture is the business logic. And as we see the business logic depends on some low level detail, namely the data layer. Therefore this business rule is already violated. And the first rule also states that both should depend on abstractions while in the layered architecture we don't see any abstractions. But in a hexagonal architecture we see that we introduce some ports which are unstable abstractions. The second rule states that abstractions should not depend on details but details should depend on abstractions. So what are the abstractions here again this hour? Again these ports should not depend on details. This is the case right here. And it also states that it should not depend on abstractions so that the details should depend on abstract so the adapters in this case should depend on the ports as well as the application core.

So the key here overall is that we introduce stable abstractions or in aesthetically type programming language we would say interfaces to that so that high level concerns are not affected by changes of low level concerns.

Also, Robert C. Martin maps this principle to a higher level. He states that components which are difficult to change should not depend on volatile components. Otherwise the volatile components will also be difficult to change. So what are the volatile components of the software system? The software volatile components are those components you want to change. So our business logic, our infrastructure code - these are things we want to change. Our software should be easy to change, right? What are the stable components in our system? The stable components of our system are the contracts we introduce between our system components. So our interfaces or maybe even some system dependency like string glass in every programming language, for example. We can express this stable dependency principle, also hexagonal architecture terms and could say ports should change infrequently and should not have dependencies.

Let's recap what we learned in the last few minutes: We learned that the real difference between layered and hexagonal architecture is that the direction of the dependencies are different. And we also learned that the hexagonal architecture fulfills the single responsibility principle by fulfilling the dependency inversion principle. And in fact, this is all possible only by introducing stable interfaces between our software components. If you are further interested in learning about hexagonal style architecture patterns and maybe even want to implement them in some of your recent projects, check out the books by Robert C. Martin and Tom Hombergs about clean architecture or check out one of the blog articles which I stated here. All of this has been used as some references for this talk. And of course I always like to have an exchange about software design topics so don't hesitate to contact me either by e-mail or on Twitter so that we can have a conversation about these topics. And who knows, maybe we can have these conversations even soon as some colleagues and one of our offices in Linz, Hagenberg or Vienna. Thanks for watching. See you around.