This post is part of The Software Architecture Chronicles, a series of posts about Software Architecture. In them, I write about what I’ve…
The traditional approach will likely bring us problems both on the front-end side and on the backend side.
On the front-end side we end up having leakage of business logic into the UI (ie. when we put use case logic in a controller or view, making it unreusable in other UI screens) or even leakage of the UI into the business logic (ie. when we create methods in our entities because of some logic we need in a template).
A port is a consumer agnostic entry and exit point to/from the application. In many languages, it will be an interface. For example, it can be an interface used to perform searches in a search engine. In our application, we will use this interface as an entry and/or exit point with no knowledge of the concrete implementation that will actually be injected where the interface is defined as a type hint.
An adapter is a class that transforms (adapts) an interface into another.
For example, an adapter implements an interface A and gets injected an interface B. When the adapter is instantiated it gets injected in its constructor an object that implements interface B. This adapter is then injected wherever interface A is needed and receives method requests that it transforms and proxies to the inner object that implements interface B.
The adapters on the left side, representing the UI, are called the Primary or Driving Adapters because they are the ones to start some action on the application, while the adapters on the right side, representing the connections to the backend tools, are called the Secondary or Driven Adapters because they always react to an action of a primary adapter.