Skip to content

Patrones DDD

Domain-Driven Design (DDD) en lg5-spring

lg5-spring implementa patrones Domain-Driven Design (DDD) en todas las capas del proyecto.

DDD: Patrones Implementados

Patrón DDDDescripciónUbicación
AggregateRootRaíz de un agregado que garantiza consistencialg5-common-domain
EntityObjeto con identidad (UUID)your-domain-core
ValueObjectObjeto inmutable sin identidadyour-domain-core
DomainEventEvento de dominio que ocurreyour-domain-core
DomainExceptionExcepción específica del dominioyour-domain-core
RepositoryPort de salida para persistenciayour-application-service
ApplicationServiceUse case coordinatoryour-application-service
CommandDTOs de entrada (CQRS)your-application-service/dto
MessageListenerPort de entrada para eventosyour-application-service

AggregateRoot

La clase base AggregateRoot<T> viene de lg5-common-domain:

java
public class User extends AggregateRoot<UserId> {
     private String firstName;
     private String lastName;
      
     public User(UserId id, String firstName, String lastName) {
          super.setId(id);
          this.firstName = firstName;
          this.lastName = lastName;
      }
}

Value Object

java
public record UserId(UUID value) {
     public UserId {
          if (value == null) throw new IllegalArgumentException("ID cannot be null");
      }
}

Domain Event

java
public class UserCreatedEvent {
     private final User user;
     private final Instant occurredOn;

     public UserCreatedEvent(User user) {
          this.user = user;
          this.occurredOn = Instant.now();
      }
}

Repository Pattern (Port de Salida)

java
// Port interface (application layer)
public interface UserRepository {
     User save(User user);
     Optional<User> findById(UserId id);
}

// Adapter implementation (infrastructure layer)
public class UserRepositoryImpl implements UserRepository {
     private final UserJPARepository jpaRepository;
     private final UserMapper mapper;

     @Override
     public User save(User user) {
          return mapper.toAggregate(
               jpaRepository.save(mapper.toEntity(user))
          );
      }
}

CQRS (Command Query Segregation)

java
// COMMANDS (Write model)
public record CreateUserCommand(UUID id, String firstName, String lastName) {}

// RESPONSES (Read model)
public record UserResponse(UUID id, String firstName, String lastName) {}

Ejemplo de Capa de Dominio

your-domain/
├── your-domain-core/                  # Pure domain
│    └── com/your/your/service/domain/
│        ├── entity/YourEntity.java       # AggregateRoot
│        ├── valueobject/YourId.java      # ValueObject
│        ├── event/YourCreatedEvent.java  # DomainEvent
│        ├── exception/YourException.java # DomainException
│        └── YourDomainService.java       # Domain logic

└── your-application-service/        # Application layer
     └── com/your/your/service/domain/
         ├── dto/
         │    ├── CreateYourCommand.java
         │    └── CreateYourResponse.java
         ├── ports/
         │    ├── input/service/YourApplicationService.java
         │    └── output/
         │        ├── repository/YourRepository.java
         │        └── messaging/YourEventPublisher.java
         ├── YourApplicationServiceImpl.java
         └── YourCommandHandler.java

Released under the MIT License.