1. Ports & Adapters Architecture
(Hexagonal Architecture)
Intent
“To allow an application to equally be driven by users, programs, automated test or batch scripts, and to be
developed and tested in isolation from its eventual run-time devices and databases.” Alistair Cockburn 2005
● Simplifies the solution by separating the code into two distinct areas, inside(domain) and
outside(infrastructural) thus preventing the mixing of Business and UI logic.
● Can provide a good insulation for change and volatility by forcing developers to program to interfaces
rather than concrete implementations.
● Reduces the amount of accidental complexity by forcing the developers to adhere to separation of
concerns and to place code in appropriate assemblies.
● Allows the solution to be more adaptive to change and helps with dependency management by ridding
the core assembly of unnecessary dependencies.
2. Complexity
A complex domain such as insurance could have very
complex business logic associated with it, this is an essential
complexity that cannot be avoided,
But complexity caused as a result of bad architecture and
mixing of business logic and infrastructural concerns is
accidental and will only lead to more technical debt.
4. Change and Volatility
Infrastructure code and the code that represents business
logic, have completely different volatility levels and the
amount of impact that they could have if they were to
experience change is also different.
5. Dependency Management and Coupling
As you develop a system, you can improve the quality of its design by reducing the coupling between the system's parts. A
good way to do this is to group the classes into packages and control the dependencies between them.You can then follow
rules about how classes in one package can call classes in another - for example, one that says that classes in the domain
layer may not call classes in the presentation package.
However, you might need to invoke methods that contradict the general dependency structure. If so, use Separated
Interface to define an interface in one package but implement it in another. This way a client that needs the dependency to
the interface can be completely unaware of the implementation. (Martin Fowler, Patterns of Enterprise Application
Architecture)
In other words:
“Develop to abstractions rather than concrete implementations.”