While working on my architecture research, I've found that two architecture approaches, namely "Ports and Adapters (Hexagonal architecture)" and "Functional core - Imperative shell", are suspiciously similar.
Ports and Adapters architecture:
Functional core - imperative shell:
Let's make slight changes into each architecture:
- Make inner core of the Ports and Adapters functional
- Make imperative shell consisting of Adapters
With these changes whole picture will look like this:
From my point of view such a combination makes great sense - advantages of both approaches are get combined. In the same time each approach adds more clarity to the combined picture: Ports and Adapters do nod clarify how core is implemented, while Functional Core - Imperative Shell does not clarify how shell should look like.
So, what do you think about this "hybrid" of two architecture patterns?
Top comments (6)
It is not a coincidence they are similar. Since Bernhardt says the "functional core, imperative shell" concept is inspired by Ports & Adapters, and essentially boils down to it, but simply on a lower level: dealing with functions, not services.
Boundaries / “Functional Core, Imperative Shell” - 2012, Gary Bernhardt, the same principle as Ports & Adapters, but on a lower level, and using FP: isolating the business logic in a functional core (pure, immutable), and interact with the outside world (impure, mutable) in an imperative shell.
“Separating the stateful parts of my program from the functional parts.” ref
“The shell is really an adapter between the functional core and the nasty external work. I’m just building adapter after adapter inside the imperative shell, to hide the external world from my functional code. In a large system, you don’t have one giant shell and one giant core; that would become a mess. What you have is lots of small functional cores, and lots of imperative shells wrapping them, communicating probably via messages. If you know the Actor Model, I’ve pretty much described it. Because that is the Actor Model.“ ref
So he ties "Functional Core, Imperative Shell" to Ports & Adapters but even also to the Actor Model. But notably he doesn't envision one giant shell and one giant core.
Makes sense. Although it may be limited how much of the Core you will be able to make purely functional.. What have you found?
In theory it should be possible to make whole core functional. In practice it more reasonable to leave some things imperative, for example logging.
Do you know of any reference implementation of the "functional core, imperative shell" architecture?
Unfortunately, no. I have plan to implement something like "Pet Clinic" using this architecture, but can't provide any estimates. In particular because there are other projects with higher priority in my list. Right now I'm working on demo project for Pragmatic Functional Java coding style.
Ok. Closest I've found is: domain-driven-hexagon.