The business logic depends on abstractions, not the implementations.
The business logic only has a dependency to an interface. So the business logic has a "uses" dependency on that interface. This interface is called a secondary port in the hexagonal architecture. The interface is also often called Repository
. A term that is more common in the clean architecture.
The adapter has an "implements" dependency on that interface.
+----------------+ uses +------------+ implements +--------------+
| business logic | ------> | Repository | <------------ | DBRepository |
+----------------+ +------------+ +--------------+
The princliple that is applied here is called the dependency inversion principle:
High-level modules should not import anything from low-level modules.
Both should depend on abstractions
Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
As a result you can easily replace the repository impelemtation, e.g. for testing purposes. So that you don't need to startup a database to test the business logic. The test will be a lot faster then.
In order to have a good abstraction you have to keep the interface technology agnostic. E.g.
public interface BadRepository {
public List<Offer> findOffers(String where); // Upps we exposed the
// implementation technology
// to the client.
// because the "where"
// parameter is
// usually a SQL where statement.
}
So you should either hide the details:
public interface GoodReository {
public List<Order> findOrders(OrderCriteria oc);
}