See the full article at http://alistair.cockburn.us/crystal/articles/hpaaa/hexagonalportsandadaptersarchitecture.htm
for a longer, more careful description in GoF pattern form.
Somewhere in the mid-90s I started drawing a symmetric architecture in which the database is considered not at the bottom of the stack, but fully outside the application, just as we recommend doing with the user. To break up perceptions about top and bottom and left and right, I drew it with a hexagonal shape, and came up with the rather stupid name HexagonalArchitecture
- because I could not think of what the 'hexagon' meant. (Note about the drawing below - I'll get around to changing that drawing to show 'adapter' instead of 'transformer' "real soon now". :)
I finally had this 'aha!' moment (June 2005) in which I saw that the facets of the hexagon are 'ports' (well, this is the part I sort of knew) and the objects between the two hexagons are 'adapters' (oddly, this was the aha!, and thanks to RebeccaWirfsBrock
for her new book ObjectDesign
for his blog entry
for providing me with the necessary WhackOnTheSideOfTheHead
to see the ports and the adapters (adaptors?)), and so the architectural pattern is PortsAndAdaptersArchitecture
. It admits of a better explanation than what I could come up with in HexagonalArchitecture
The facets of the hexagon represent different conversations that the application is having with the outside world. Here is an example from a system a friend of mine was building, one that accepted notification from the weather bureau about tornados and flash floods and would phone people and leave messages on their answering machines about evacuation procedures. In the common implementation, and indeed the one he was using, there would be technology-driven interfaces, one for http protocols, one for answering machines, one for people, one for a database. My friend was running into trouble maintaining and extending his system as it progressed. Together we identified the following different sorts of conversations going on:
- Notification stuff about weather events
- Database-y stuff, like who is subscribed and where they want notifications sent
- Evacuation procedure stuff, whether given to a person or a recording device
- Administration control stuff, like setting up notification events, billing, updating user base, parameters of the application, and so on
We saw there four fundamentally different conversations, and said that the application should have an API for each of these, and talk through those four ports
to whatever was sitting on the other side of the port. He would create an adapter for each different technology sitting out there.
To justify this idea of ports
, we wanted to test that there really were multiple external technologies on the other side of each port, such that it was worth having an adapter present to adjust the external technology to the API.
We got the first obvious one that the Admin person would be replaced by a suite of automated tests (you can of course do this in your system, can't you?). We got the next one that the database would be replaced by a LoopBack
mechanism (you can of course do this in your system, can't you?). What finally got his attention was when he finally saw that he had a requirement to add the possibility for customers to replace the telephone answering machine with a web or email notification; and also that the notification stuff was about to be augmented from a straight API with the weather bureau to an http interface. That is, he really was going to need (read: could benefit from) having two different adapters hanging off each port. And once he got to two, he could suddenly see a third, namely, the individual applications in his complex of applications that was his product set. He would create adapters (or direct hookups) to allow one application to talk through the port of another application. This would modularize his system in just the way he was just then trying to accomplish, and let his applications drive each other without needing special and weird side pathways to each other.
This was the most explicit use of the 'ports' concept I have run across --- usually there are only 2, the user and the database.
The following explanation from HexagonalArchitecture
still applies, updated for 'ports' and 'adapters': Each face of the hexagon (port) represents some "reason" the application is trying to talk with the outside world.
Events arrive from the outside world at a port. The adapter converts it into a usable procedure call or message and passes it to the application. The application is blissfully ignorant of the nature of the input device (see also Ward's CHECKS pattern language, http://c2.com/ppr/checks.html
When the application has something to send out, it sends it out the port to the adapter, which creates the appropriate signals needed by the receiving technology (human or automated). The application has a semantically sound interaction with the adapters on all sides of it, without actually knowing the nature of the thing on the other side of the adapter.
Also discussions about the BarryRubel?
paper about Pedastals to create an axis of symmetry in control software (in the paper "Patterns for Generating a Layered Architecture", from PatternLanguagesOfProgramDesign
) still apply.
Maybe you could call it the 'Pompidou Architecture', or 'InsideOut?
Architecture' or 'Radical Expressionist' etc? I'm only half joking. The key point is that, like Roger's building architecture, the infrastructure is pluggable AND exposed.
The operating space (the interior) is completely devoid of infrastructure except at the operational interfaces e.g. power points, air conditioning vents versus database ports, user access port, etc.
Of course 'inside' and 'outside' are abstractions in computer space, but I think the metaphor holds :).
This suggests to me one of those ThingsInThrees
. The diagram can be viewed as having three component types - the application domain, the transform, and reality. The ApplicationTransformReality?
model. Transforming reality has a good ring to it. -- PeterLynch
In one project I worked on, we used the SystemMetaphor
of a component stereo system. Each component has defined interfaces, each of which has a specific purpose. We can then connect components together in almost unlimited ways using simple cables and adapters.
I encountered something similar, but mainly because my application layer had a strong tendency to become a telephone switchboard that managed things it should not do. My application generated output, showed it to the user and then had some possibility to store it as well. My main problem was that you did not need to store it always. So my application generated output, had to buffer it and present it to the user. Then, when the user decided that he wanted to store the output, the application retrieved the buffer and stored it for real.
I did not like this at all. Then I came up with a beautiful solution: Have a presentation control with storage facilities. Now the application no longer channels the output in different directions, but simply outputs it to the presentation control. It's the presentation control that buffers the answer and gives the user the possibility to store it.
The traditional layered architecture stresses "UI" and "storage" to be different. The PortsAndAdaptersArchitecture
can reduce output to being simply "output" again. -- WillemBogaerts