Cómo aplicar Arquitectura Limpia en Laravel

PUBLICADO: 2026-07-22
AUTOR: MANUEL PRIETO
Architecture

Llevar los conceptos teóricos de la Arquitectura Limpia a un framework moderno de PHP como Laravel puede parecer desafiante debido al acoplamiento natural que promueve el patrón Active Record de Eloquent. Sin embargo, es perfectamente viable diseñar una separación estricta para garantizar que nuestro núcleo de negocio sea independiente del framework y 100% testable.

Para lograrlo, aplicaremos la Regla de DependenciaRegla de DependenciaPrincipio central de la Arquitectura Limpia que establece que las dependencias del código fuente solo pueden apuntar hacia adentro, es decir, hacia las capas que contienen la lógica de negocio y las reglas empresariales (Entidades y Casos de Uso). Ningún componente o clase de un círculo interno puede conocer, importar o hacer referencia directa a elementos ubicados en círculos externos (como frameworks, bases de datos o la interfaz de usuario).: todas las dependencias del código fuente deben apuntar hacia adentro, aislando Laravel y sus bases de datos en los círculos externos del sistema. Si necesitas revisar primero las bases teóricas y las cuatro capas concéntricas, te recomendamos leer nuestro artículo sobre los fundamentos de la Arquitectura Limpia.

Organización de Capas en la Estructura de Directorios

Para estructurar las capas dentro de la carpeta app/ de Laravel, utilizaremos espacios de nombres dedicados a separar responsabilidades:

  • App/Domain: Contiene las EntidadesEntidad (Entity)El núcleo inamovible de la lógica de negocio en la Arquitectura Limpia. Una Entidad encapsula las reglas y datos empresariales más fundamentales y generales (las reglas de negocio críticas). Pueden ser objetos con métodos o un conjunto de estructuras de datos y funciones, y son completamente ajenas a cualquier cambio externo, como modificaciones en la base de datos, en el sistema de vistas o en el framework de desarrollo. y las interfaces de los contratos. Esta capa es pura teoría de negocio y no importa absolutamente nada de Laravel.
  • App/Application: Contiene los Casos de UsoCaso de Uso (Use Case)Estructura que define y representa una acción o flujo de negocio específico que un usuario o sistema puede realizar dentro de la aplicación. En Arquitectura Limpia, los Casos de Uso se ubican en la capa de aplicación y orquestan el flujo de datos desde y hacia las entidades, ejecutando las reglas de negocio específicas de la aplicación. Son completamente independientes de cómo se presentan los datos, de los frameworks y de los mecanismos de persistencia. (servicios de aplicación) y las estructuras de transferencia de datos (DTOsData Transfer Object (DTO)Objeto de transferencia de datos. Es un patrón de diseño de software cuyo propósito es transportar datos entre procesos o capas de una aplicación, sin contener lógica de negocio. En arquitecturas desacopladas como la Arquitectura Limpia, los DTOs se utilizan para transferir información de forma segura y fuertemente tipada desde los adaptadores externos (como controladores HTTP o comandos de consola) hacia los Casos de Uso en la capa de aplicación. Esto previene que el núcleo del sistema se acople a peticiones HTTP crudas o a estructuras de persistencia específicas.).
  • App/Infrastructure: Contiene la implementación concreta de la persistencia de datos (como la base de datos a través de Eloquent), APIs externas y controladores.

Implementando el Núcleo: Entidades y Contratos de Dominio

La capa más interna es el Dominio. Aquí no existen modelos de base de datos ni llamadas a clases externas. Definimos una EntidadEntidad (Entity)El núcleo inamovible de la lógica de negocio en la Arquitectura Limpia. Una Entidad encapsula las reglas y datos empresariales más fundamentales y generales (las reglas de negocio críticas). Pueden ser objetos con métodos o un conjunto de estructuras de datos y funciones, y son completamente ajenas a cualquier cambio externo, como modificaciones en la base de datos, en el sistema de vistas o en el framework de desarrollo. de negocio pura en PHP:

A continuación, definimos el contrato que necesitará la aplicación para buscar y guardar usuarios. Este contrato es una implementación del Patrón RepositorioPatrón Repositorio (Repository Pattern)Patrón de diseño que actúa como una capa de abstracción entre la lógica de negocio y la capa de acceso a datos. Define interfaces (contratos) en el núcleo de la aplicación que especifican cómo guardar, buscar o actualizar datos, sin detallar el mecanismo de almacenamiento real (como bases de datos SQL, NoSQL o llamadas a APIs). La implementación concreta de esta interfaz se delega a la capa externa de infraestructura, permitiendo cambiar el motor de persistencia sin modificar las reglas de negocio. y un ejemplo del principio de inversión de dependencias de SOLIDSOLIDAcrónimo de cinco principios de diseño orientado a objetos y programación diseñados para hacer que el software sea más comprensible, flexible y mantenible: S - Single Responsibility Principle (Responsabilidad Única) O - Open/Closed Principle (Abierto/Cerrado) L - Liskov Substitution Principle (Sustitución de Liskov) I - Interface Segregation Principle (Segregación de Interfaz) D - Dependency Inversion Principle (Inversión de Dependencias) :

Orquestación: Casos de Uso y DTOs

En la capa de aplicación creamos el Caso de UsoCaso de Uso (Use Case)Estructura que define y representa una acción o flujo de negocio específico que un usuario o sistema puede realizar dentro de la aplicación. En Arquitectura Limpia, los Casos de Uso se ubican en la capa de aplicación y orquestan el flujo de datos desde y hacia las entidades, ejecutando las reglas de negocio específicas de la aplicación. Son completamente independientes de cómo se presentan los datos, de los frameworks y de los mecanismos de persistencia.. Este se encarga de ejecutar el flujo de negocio llamando a los repositoriosPatrón Repositorio (Repository Pattern)Patrón de diseño que actúa como una capa de abstracción entre la lógica de negocio y la capa de acceso a datos. Define interfaces (contratos) en el núcleo de la aplicación que especifican cómo guardar, buscar o actualizar datos, sin detallar el mecanismo de almacenamiento real (como bases de datos SQL, NoSQL o llamadas a APIs). La implementación concreta de esta interfaz se delega a la capa externa de infraestructura, permitiendo cambiar el motor de persistencia sin modificar las reglas de negocio. e interactuando con las entidadesEntidad (Entity)El núcleo inamovible de la lógica de negocio en la Arquitectura Limpia. Una Entidad encapsula las reglas y datos empresariales más fundamentales y generales (las reglas de negocio críticas). Pueden ser objetos con métodos o un conjunto de estructuras de datos y funciones, y son completamente ajenas a cualquier cambio externo, como modificaciones en la base de datos, en el sistema de vistas o en el framework de desarrollo.. Para pasar datos de forma segura entre las capas externas y los casos de uso, implementamos un Data Transfer Object (DTO)Data Transfer Object (DTO)Objeto de transferencia de datos. Es un patrón de diseño de software cuyo propósito es transportar datos entre procesos o capas de una aplicación, sin contener lógica de negocio. En arquitecturas desacopladas como la Arquitectura Limpia, los DTOs se utilizan para transferir información de forma segura y fuertemente tipada desde los adaptadores externos (como controladores HTTP o comandos de consola) hacia los Casos de Uso en la capa de aplicación. Esto previene que el núcleo del sistema se acople a peticiones HTTP crudas o a estructuras de persistencia específicas. simple:

Ahora creamos el Caso de Uso encargado de registrar al usuario, aplicando el principio DRYDRY (Don't Repeat Yourself)Principio fundamental de diseño de software formulado por Andy Hunt y Dave Thomas. Establece que toda pieza de conocimiento o lógica debe tener una representación única, no ambigua y definitiva en el sistema para evitar duplicidad y facilitar el mantenimiento. al encapsular esta lógica en un único lugar del sistema:

Adaptación e Infraestructura: Modelos de Laravel y Repositorios

Para cumplir los principios de la Arquitectura Limpia en Laravel, tratamos los modelos del ORMObject-Relational Mapping (ORM)Mapeo Objeto-Relacional. Técnica o herramienta de programación que permite traducir la estructura de una base de datos relacional (tablas y registros) a objetos del lenguaje de programación, facilitando la interacción con el almacenamiento de datos mediante código orientado a objetos en lugar de consultas SQL crudas. En Laravel, Eloquent es el ORM integrado, y en Arquitectura Limpia se le considera un detalle externo y de infraestructura que el dominio de la aplicación no debe conocer directamente. Eloquent y las tablas físicas como detalles externos del círculo de infraestructura:

  1. Modelos Eloquent: Los modelos en app/Models son infraestructura pura y se acoplan a la base de datos externa.
  2. RepositoriosPatrón Repositorio (Repository Pattern)Patrón de diseño que actúa como una capa de abstracción entre la lógica de negocio y la capa de acceso a datos. Define interfaces (contratos) en el núcleo de la aplicación que especifican cómo guardar, buscar o actualizar datos, sin detallar el mecanismo de almacenamiento real (como bases de datos SQL, NoSQL o llamadas a APIs). La implementación concreta de esta interfaz se delega a la capa externa de infraestructura, permitiendo cambiar el motor de persistencia sin modificar las reglas de negocio. Concretos: Creamos una clase concreta en la capa de infraestructura que implemente la interfaz del dominio. Esta clase realiza la persistencia consultando y actualizando el modelo Eloquent, encargándose de traducir el modelo del framework a la entidadEntidad (Entity)El núcleo inamovible de la lógica de negocio en la Arquitectura Limpia. Una Entidad encapsula las reglas y datos empresariales más fundamentales y generales (las reglas de negocio críticas). Pueden ser objetos con métodos o un conjunto de estructuras de datos y funciones, y son completamente ajenas a cualquier cambio externo, como modificaciones en la base de datos, en el sistema de vistas o en el framework de desarrollo. pura del dominio.

Configuración y Enlace de Servicios

Para que Laravel inyecte automáticamente la implementación correcta de EloquentUserRepository cuando una clase requiera la interfaz UserRepositoryInterface, registramos la asociación en el contenedor de servicios de Laravel, normalmente en app/Providers/AppServiceProvider.php:

El Punto de Entrada Externo: Controladores HTTP

El controlador HTTP es parte de la capa externa de adaptadores e infraestructura. Recibe la petición, valida la entrada, instancia el DTO y dispara el caso de uso correspondiente:

Diseñar nuestras aplicaciones PHP siguiendo esta estructura nos permite aislar completamente la lógica central de negocio de las decisiones técnicas y de infraestructura, asegurando la escalabilidad del sistema y facilitando la realización de test unitarios robustos sobre el dominio.