- Tags:: 📝CuratedNotes, Software Architecture, DDD
Diagram:
Link to original![]()
Originally described in Hexagonal architecture by Alistair Cockburn. It can be seen as an evolution to Traditional Layered Architecture after applying the Dependency Inversion Principle. From đź“– Implementing Domain-Driven Design:
Link to originalInterestingly enough, when we think about the influence that DIP has on this architecture, we might conclude that there are actually no longer any layers at all. Both high-level and low-level concerns are dependent only on abstractions, which seems to topple the stack. (p. 125)
Ports and adapters
Then, there is only an “outside” and an “inside”. The “inside”, the app, exposes interfaces and the “outside” implements those interfaces. Ports are the interfaces with the outside world and the adapters are implementations of those interfaces.
Note however that, although there is a symmetric use in the ports and adapters…
All the adapters, both driver and driven, depends on the hexagon. The application is technology agnostic in both sides. (Hexagonal Architecture - Ports ans Adapters Pattern | Hexagonal Me)
… there is a distinction between:
- the driver ports and adapters. The port would be the API of the application layer (the use cases it exposes), and the adapters would translate outside world requests into calls to the application (e.g., a REST controller).
- the driven ports and adapters, the Service Provider Interface (SPI) of the application, that are used by the app (e.g., writing to a database). The port would be an interface at the application layer and the adapters would implement that interface in the infra layer.
Asymmetry: Configurable Dependency implementation is different for each side. In the driver side, the application doesn’t know about which adapter is driving it. But in the driven side, the application must know which driven adapter it must talk to. (Hexagonal Architecture - Ports ans Adapters Pattern | Hexagonal Me)
Note that the ports may not always be explicit interfaces in our app:
Link to originalWe actually normally don’t implement the Ports ourselves. Think of a Port as HTTP and the Adapter as a Java Servlet or JAX-RS annotated class that receives method invocations from a container (JEE) or framework (RESTEasy or Jersey). Or we might create a message listener for NServiceBus or RabbitMQ. In that case the Port is more or less the messaging mechanism, and the Adapter is the message listener (p. 127)
Or see the code structure of 📖 Architecture Patterns With Python, in which the “entrypoints” (a Flask app) doesn’t really refer to an explicit interface.
Also, although the Ports (the interfaces) belong to the high-level layer that will use them (e.g., a repository interface in the Domain or Application layer) and the implementation to the low-level layer (e.g., Infrastructure), it is common to have simply an “adapter” folder with the interface and the implementation.
Layers?
Although it seems the original article only refers to an application boundary and it does not make any reference to layers…
Ports & Adapters pattern says nothing about the structure of the inside of the hexagon.(…) Many articles I’ve read about this architecture say that it is a layered one. They talk about three layers: domain, ports, adapters. I don’t know why they say such thing, the pattern says nothing about layers. The pattern just says that we have the application (the hexagon), with a given number of ports, and that for each port we can have different adapters, each one using a technology. There’s no layers nowhere. (Hexagonal Architecture - Ports ans Adapters Pattern | Hexagonal Me)
…the same concept can be used with layers inside the hexagon, and thus, with a Domain Model for DDD. From Hexagonal Architecture - Fideloper: