Reputation: 111
As I was reading a lot lately regarding the Ports and Adapters architecture, I stumbled upon this piece of code as a part of an application that was build following the above mentioned architecture :
package com.example.user.management;
import lombok.*;
import javax.persistence.*;
import java.io.Serializable;
@Table(name = "user")
@AllArgsConstructor
@Data
@NoArgsConstructor
@javax.persistence.Entity
@Setter
@Getter
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Column(name = "role")
private String role;
public User(String username, String password, String role) {
this.username = username;
this.password = password;
this.role = role;
}
}
As the main intent of the Ports and Adapters architecture is to separate and isolate the domain layer from any technical details and implementations, and having in mind that this User entity is in fact, the domain layer, doesn't it contain dependency to the java persistence library? As I understand it, the domain layer is responsible only for implementing the use-cases. I am really confused as per what should actually be the Domain Layer in this type of architecture.
Upvotes: 6
Views: 2809
Reputation: 4754
As the main intent of the Ports and Adapters architecture is to separate and isolate the domain layer from any technical details and implementations
The intention is to isolate the application from things that don't belong to the real problem the application has to solve. Those things are input/output devices, databases, technology frameworks, etc. The application code must be clean code. But the pattern says nothing about how you must structure the inside of the hexagon. You may have a domain layer or not, it's up to you.
this User entity is in fact, the domain layer, doesn't it contain dependency to the java persistence library?
Assuming you have a domain model inside de application with a User entity, the code you show here isn't that User entity. The domain model User entity must be tecnnology agnostic, no annotations, no framework code. The code you show here would belong to the persistence adapter that use JPA to access the database. In that adapter you would have to translate between the User entity of the domain model and this JPA User entity.
As I understand it, the domain layer is responsible only for implementing the use-cases.
According to DDD (domain driven design), Domain layer doesn't implement use-cases. Application layer does. And application layer calls domain layer in order to do it. But these concepts of layers, DDD, etc have nothing to do with Ports and Adapters architecture. The pattern says nothing about it.
I am really confused as per what should actually be the Domain Layer in this type of architecture.
This architecture doesn't say anything about what the Domain Layer should be. This architecture just says that you have an application (hexagon), ports (API/SPI belonging to the hexagon), and adapters (outside the hexagon). Whatever layers you put inside the hexagon is up to you, being Domain Layer or whatever.
Upvotes: 1
Reputation: 17104
Excellent question, first note that hexagonal architecture does not have layers. Hexagonal architecture has an application and adapters with a one-way relationship between the two, nothing more. There is no domain layer.
The application communicates to its adapters using mere POJOs (without imports). These live in the application and are shared by the adapters. When an adapter needs to customize (adapt) one of these POJOs, it implements its own custom version of that object (e.g. via composition or inheritance). This splits the domain into what you might call the domain API and the domain implementation.
The domain API is specified by the application. This API must be agnostic of the technologies used by the adapters. So you are correct to say that javax.persistence
doesn't belong in the domain API inside the application.
The code example in question is what you might call a domain implementation. It includes "plugin" technologies which the application is (and must remain) unaware of.
So you would put a POJO inside the application (without persistence annotations) and the above code would live inside e.g. a relational database adapter that would convert its domain implementation to the application's domain API.
Upvotes: 6