Arquitectura en Capas en el Diseño Orientado al Dominio (DDD)

La arquitectura en capas es un patrón fundamental en el desarrollo de sistemas. Aunque una implementación estrictamente separada puede ser teóricamente ideal, en la práctica es común la hibridación de varios patrones arquitectónicos. Esto puede llevar a confusiones sobre la clasificación y dependencia de los componentes.

Arquitectura Estrictamente Encapada

Comúnmente, la arquitectura en capas se explica mediante definiciones conceptuales o modelos como el de las siete capas OSI. La idea principal es dividir una aplicación en grupos de subtareas, cada una residiando en una capa de abstracción específica.

Para una implementación concreta, las reglas clave son:

  • Las capas adyacentes deben tener un acoplamiento unidireccional. Una capa superior solo puede depender de una capa inferior, nunca al revés.
  • La comunicación entre capas adyacentes también debe ser unidireccional. Una capa superior llama a las interfaces proporcionadas por una capa inferior, pero una capa inferior nunca llama a una capa superior.

Existen especificaciones más detalladas, pero el principal desafío suele radicar en mantener la dependencia unidireccional, especialmente al estructurar el código en directorios. La asignación de ciertos objetos a capas específicas puede generar ambigüedad.

Arquitectura en Capas Relajada (Relaxed Layered System)

Dentro del Diseño Orientado al Dominio (DDD), se prefiere una arquitectura en capas más flexible. Las capas pueden utilizar servicios de cualquier capa inferior, no solo de la inmediatamente adyacente. Las capas pueden ser semi-transparentes, es decir, algunos servicios solo son visibles para la capa superior directa, mientras que otros son accesibles para todas las capas superiores.

Es crucial recordar que, incluso en este modelo, la dependencia sigue siendo unidireccional: las capas superiores solo pueden invocar servicios de las capas inferiores.

Arquitectura en Capas por Herencia (Layering Through Inheritance)

Otra variante utilizada en DDD es la arquitectura en capas por herencia. En este enfoque, las capas superiores heredan e implementan interfaces definidas en capas inferiores. Esto a menudo implica reordenar las capas, moviendo la capa de infraestructura a la parte superior.

Nuevamente, la dependencia es unidireccional. La capa de dominio, aplicación y presentación no dependen de la infraestructura; en cambio, la infraestructura puede depender de ellas.

Ejemplo de interfaz en la capa de dominio:


package com.mallfoundry.user.domain;

public interface UserRepository {
    User save(User user);
}

Ejemplo de implementación en la capa de infraestructura (persistencia):


package com.mallfoundry.user.infrastructure.persistence;

import javax.persistence.EntityManager;

public class JpaUserRepository implements UserRepository {

    private final EntityManager entityManager;

    public JpaUserRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public User save(User user) {
        return this.entityManager.merge(user);
    }
}

Paquetes y Arquitectura en Capas

Si bien los paquetes se utilizan para organizar las capas, el nombre del paquete en sí mismo no garantiza la aplicación correcta de la arquitectura en capas.

Repositorios

Generalmente, las implementaciones de repositorios se ubican en la capa de infraestructura, especialmente si se utiliza la arquitectura por herencia. Si se opta por una arquitectura en capas relajada, la implementación del repositorio podría residir en la capa de dominio. Esto se debe a la regla de dependencia unidireccional; no hay justificación para romper este principio a menos que no se esté utilizando una arquitectura en capas.

Arquitectura de Tres o Cuatro Capas

La evolución histórica de las arquitecturas de sistemas, especialmente en el contexto de arquitecturas cliente-servidor separadas (frontend/backend), ha llevado a diferentes divisiones en capas:

  • Etapa 1: Dos Capas (Presentación y Base de Datos). La lógica de acceso a datos se incrustaba directamente en la capa de presentación, interactuando con la base de datos mediante interfaces como JDBC.
  • Etapa 2: Tres Capas (Presentación, Dominio y Base de Datos). Se introduce el concepto de modelo. La presentación ya no manipula directamente estructuras de datos crudas (como ResultSet), sino objetos o estructuras que representan conceptos del dominio.
  • Etapa 3: Cuatro Capas (Presentación, Lógica de Negocio de Aplicación, Dominio y Base de Datos). La lógica de negocio, que antes residía en la presentación, se extrae a una capa de aplicación dedicada. La capa de presentación adopta patrones como MVC, desacoplando la vista y permitiendo que el controlador orqueste la lógica de negocio y la presentación de datos.

La arquitectura de cuatro capas se considera madura para muchos sistemas. Para profundizar en el contexto de DDD, se añaden consideraciones adicionales:

  • Etapa 4: Influencia del Diseño Orientado a Objetos. El enfoque se desplaza hacia el modelado del dominio con objetos (propiedades y operaciones). La lógica de negocio de la aplicación es asumida en gran medida por estos modelos de dominio, y la capa de aplicación actúa como orquestadora. Este enfoque está detalladamente expuesto en el libro "Domain-Driven Design" de Eric Evans.
  • Etapa 5: Impacto de la Separación Frontend/Backend. Con la arquitectura frontend/backend separada, la capa de presentación se externaliza completamente. El backend se centra en exponer APIs (RESTful, gRPC, etc.). Las arquitecturas de backend resultantes pueden seguir patrones como Backend For Frontend (BFF) o patrones basados en objetos de agregación, diferenciándose en su adaptabilidad a cambios frecuentes en el frontend.

Comercio Electrónico de Código Abierto

Mallfoundry es una plataforma de comercio electrónico multi-tenant de código abierto desarrrollada con Spring Boot. Puede integrarse en aplicaciones Java existentes o funcionar como un servicio independiente.

  • El modelo de dominio se basa en DDD, interfaces y diseño orientado a objetos.

Dirección del proyecto: https://gitee.com/mallfoundry/mall

¡Considera darle una estrella si te resulta útil!

Etiquetas: DDD Arquitectura en Capas Diseño Orientado a Objetos Spring Boot Microservicios

Publicado el 9-22 22:48