A few weeks back at our monthly #PETechtalk for Deloitte Platform Engineering, I spoke about "Hexagonal Architecture" and how exploring the past can help us to build our future. I promised those who attended I would follow up with a blog article giving you the highlights we went through and also provide some of the rich and useful resources that I discovered in putting this presentation together… and so here it is.
Having been in the industry since the '90s, it was very nostalgic for me to look back to the way we developed software in 2005 and how something like "Hexagonal Architecture" has stood the test of time. Often attributed as being the foundation for the modern Microservice Architecture we use today(ref 1),(ref 2), those credited with its inception have been involved in some of the most influential changes our industry has seen in the last 20 years.
Colloquially this term has been used to describe 3 different patterns, each of which built upon (and gave credit to) the architectures that preceded them:
While each of these patterns has a different focus, the taxonomy of this architecture can be seen through 3 distinctive attributes that appear across all of them:
From this structure we can summarize 4 key features promoted by the architecture:
Looking at this architecture can often be daunting, and indeed implementing a purely hexagonal application does require a lot of discipline and care. There are however easier ways to put this into practice by picking your battles and choosing when to adhere to these principles and when not to.
An example of this would be to combine the Mediator pattern with dependency inversion and use the System.CompositionModel.Composition namespace (previously known as MEF) to dynamically load observers as adaptors into your solution.
Imagine a report generator that may have a variety of different technologies it could use to report its data, perhaps you can output to PDF, or Microsoft Word, or even HTML.
Without the use of hexagonal architecture, your report generator would be dependent on all these technologies at the same time, and any updates to one would require updating the entire application.
By putting each of these technologies into separate adaptors you isolate the technology to the outside, which frees up the report generator to now be tested in complete isolation, agnostic of any of the technologies being used.
Your report generator now “drives” the adaptors to perform its task, making it more modular and supporting better maintainability. New adaptors can be created without needing to update or deploy the entire application.
Whether you are interested in implementing the architecture in its entirety, or just making good use of some of the principles that it promotes, looking back at how these architectures came about can often provide a great wealth of knowledge to help us build our future.
If you want to look deeper into this architecture from a practical standpoint, several projects can be found on git hub to support this:
Language | Author | Title |
Java | Tom Homberg | Example implementation of Hexagonal Architecture |
C# | Ivan Paulovich | Acerola: Hexagonal Architecture |
C# | Thomas Pierrain | hexagonalThis |
Ruby | Pat Maddox | Haxarch2 |
PHP | Brian Webb | Hexagonal Laravel Architecture |
Go | Akbar Shaikh | Denti-go-clean-arch |
Python | Sebastian Buczynski | Implementing the Clean Architecture |
Here is some additional reading which you may find useful. If nothing else I would recommend you check out the YouTube video “Hexagone” which is the only record of Alistair Cockburn lecturing on his original Ports and Adaptors pattern.