Table of Contents
La arquitectura limpia es más que una palabra de zumbido en el desarrollo moderno del software, es un enfoque deliberado y estructurado para diseñar sistemas que resistan la prueba del tiempo. En su núcleo, la arquitectura limpia proporciona un conjunto de directrices para la organización del código de modo que la lógica empresarial siga siendo independiente de influencias externas como marcos, bases de datos, interfaces de usuario y servicios de terceros. Esta independencia hace que la base de código sea más fácil de mantener, probar y adaptar como evolucionan los requisitos de la arquitectura.
¿Qué es la arquitectura limpia?
Arquitectura limpia fue popularizada por Robert C. Martin (a menudo conocido como tío Bob) en su libro ] Arquitectura limpia: Guía de artesanos para la estructura y diseño del software] y en una serie de publicaciones del blog. La filosofía central es separar las preocupaciones definiendo capas concéntricos de responsabilidad, con la capa más interna que contiene la lógica de negocio más pura y los componentes de la red exterior
Este enfoque no es radicalmente nuevo, sino que se basa en patrones anteriores como la arquitectura hexagonal (Alistair Cockburn), la arquitectura de la cebolla (Jeffrey Palermo), y el diseño impulsado por el dominio (Eric Evans). Lo que la arquitectura limpia trae a la tabla es un conjunto claro y repetible de reglas que cualquier equipo puede adoptar, independientemente del lenguaje o marco.
Al aplicar esta regla, los desarrolladores aseguran que los cambios en los marcos, bases de datos o tecnologías de la interfaz no se desborden hacia adentro para corromper la lógica empresarial básica. El sistema se vuelve fundamentalmente resistente a la tecnología.
Principios clave de la arquitectura limpia
Los principios están diseñados para orientar la toma de decisiones durante todo el ciclo de vida de un proyecto. Examinemos cada principio en profundidad.
1. Independencia de los marcos
Un marco es una herramienta, no la base de su sistema. En la arquitectura limpia, su lógica de negocio no debe ser duramente a un marco específico. Por ejemplo, si usted está construyendo una aplicación web con un marco como React, Angular, o Vue, la lógica de dominio básico no debe importar componentes de React o referencia Servicios Angulares. En lugar, el marco debe ser tratado como una preocupación externa que se conecta a interfaces bien definidas.
2. Testability
Cuando las reglas de negocio están aisladas de dependencias externas, se vuelven trivialmente testables. Puede escribir pruebas de unidad para entidades y utilizar casos sin hacer un seguimiento de una base de datos, burlar un servidor HTTP o cargar una interfaz de usuario. Esta velocidad y fiabilidad de las pruebas alienta a los desarrolladores a probar más a menudo y más temprano, capturando errores antes de que se intensifiquen. Además, debido a que las capas externas (como bases de datos y API) también están diseñadas alrededor de las pruebas de integración de datos, puede verificar fácilmente
3. Separación de las preocupaciones
La herramienta de diseño de la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información y la tecnología de la información.
4. El Estado de dependencia
Esta regla es el pegamento que mantiene la arquitectura juntos. Afirma que las dependencias del código fuente siempre deben apuntar hacia adentro: desde capas externas hacia capas interiores. Ninguna capa interna debe saber nunca sobre una capa externa. En la práctica, esto significa que las interfaces definidas en los casos de uso y las entidades son propiedad de esas capas internas. capas externas implementan esas interfaces – no las dictan. Por ejemplo, si un caso de uso necesita para adaptar un usuario[LT]
Capas de Arquitectura Limpia
Mientras que el número de capas puede variar dependiendo del proyecto, el diagrama de arquitectura limpia canónica muestra cuatro anillos concéntricos. Entender cada capa es esencial para aplicar correctamente los principios.
Entidades (Reglas de Negocios de la Administración)
Las entidades son la parte más estable del sistema. Encapsulan las reglas básicas de negocio que son aplicables en toda la organización. Por ejemplo, en un sistema bancario, una entidad contiene métodos como y que imponen a los invariantes como "el equilibrio nunca debe ir por debajo de cero". Las entidades son objetos o estructuras generalmente simples sin dependencia del marco de negocio.
Casos de uso (Reglas de negocio de aplicación)
Los casos de uso definen cómo el sistema se comporta desde la perspectiva de un actor (usuario humano, otro sistema o un temporizador). Orquestan el flujo de datos a y desde entidades y dirigen a las entidades para ejecutar sus reglas de negocio. Por ejemplo, un llamaría métodos a las entidades y luego persistía el resultado a través de una interfaz de repositorio.
Adaptadores de interfaz
Esta capa convierte los datos entre el formato más conveniente para casos de uso y entidades (estructuras de datos típicamente simples) y el formato requerido por agencias externas.
- Controladores que analizan las solicitudes de HTTP y llaman el caso de uso adecuado.
- Presenters] que transforman la salida de la caja de uso en un formato adecuado para la interfaz de usuario, como un modelo de visión.
- Puertas de base de datos que implementan interfaces de repositorio y traducen entre datos de entidad y operaciones SQL o NoSQL.
- Adaptadores de clientes de API que llaman servicios externos y convierten respuestas en estructuras de datos de la capa interna.
La capa de adaptador es donde vive la mayor parte del código "glue". También es la capa que tiende a cambiar con más frecuencia a medida que evolucionan las tecnologías externas.
Marcos y controladores
El anillo más externo contiene todas las tecnologías concretas que el sistema utiliza: el servidor web (por ejemplo, Express, Django, Spring Boot), el sistema de gestión de bases de datos (por ejemplo, PostgreSQL, MongoDB), el marco de la interfaz de usuario (por ejemplo, React, Angular), etc. Esta capa debe ser tan delgada como sea posible. Su trabajo primario es conectar la aplicación por medio de la inyección de los casos apropiados
Beneficios de usar arquitectura limpia
Adoptar arquitectura limpia produce ventajas concretas y a largo plazo que superan el esfuerzo inicial de estructurar código de esta manera.
- Mantenibilidad: Cuando se necesita cambiar una característica, modifica sólo el caso de uso relevante y sus entidades, no toda la aplicación. Debido a que las dependencias se dirigen hacia adentro, los cambios en las capas externas (como cambiar una base de datos) raramente se desencadenan en la lógica empresarial.
- Testabilidad: Como se mencionó anteriormente, el bajo acoplamiento significa que puede probar reglas de negocio en aislamiento sin establecer un entorno completo. Esto conduce a la mayor rapidez de los lazos de retroalimentación y mayor confianza en el código.
- Flexibilidad: Puede posponer las decisiones sobre infraestructura. Por ejemplo, puede comenzar con una simple persistencia basada en archivos y luego cambiar a una base de datos relacional sin reescribir la lógica de negocio, siempre y cuando la interfaz de repositorio siga siendo la misma.
- ]Scalability: La arquitectura limpia no hace automáticamente la escala del sistema horizontalmente, pero sí soporta la escalabilidad del equipo. Al separar las preocupaciones en capas, los diferentes miembros del equipo (o incluso diferentes equipos) pueden trabajar en la interfaz de usuario, la base de datos y la lógica empresarial simultáneamente sin pisar los dedos de los dedos de los otros.
- A bordo y colaboración: Los nuevos desarrolladores pueden entender la estructura general rápidamente porque la arquitectura sigue un patrón bien conocido. Pueden bucear en capas específicas sin necesidad de entender toda la base de código.
Para una inmersión más profunda en la motivación detrás de este patrón, puede leer el original de Robert C. Martin ] Publicación de blog de arquitectura fina o explorar Martin Fowler's discussion on domain-oriented observability], que complementa la filosofía de arquitectura limpia.
Implementación de Arquitectura Limpia en la Práctica
La transición a la arquitectura limpia puede sentirse intimidante, especialmente si usted está trabajando con una base de código heredada. Los siguientes pasos prácticos le ayudarán a empezar.
Paso 1: Identificar e izar el dominio del núcleo
Comience examinando su código existente para localizar las reglas de negocio puras. Estas son las partes que todavía tendrían sentido si usted reemplazó la base de datos o la interfaz de usuario mañana. Extráigalos en un módulo separado (por ejemplo, un paquete, una carpeta o un microservicio) sin dependencias externas. Este módulo se convertirá en sus entidades y utilizará casos.
Paso 2: Definir las interfaces para las interacciones externas
Para cada operación que requiere un sistema externo (database, sistema de archivos, red, interfaz de usuario), definir una interfaz desde la perspectiva del núcleo. Por ejemplo, crear una interfaz con métodos como y . No te preocupes por la implementación todavía; la interfaz pertenece al núcleo.
Paso 3: Construir adaptadores que implementen esas interfaces
Ahora crear clases de hormigón en las capas exteriores que implementan las interfaces. Para un adaptador de base, esto podría ser una clase de repositorio que utiliza su ORM o SQL crudo. Para un adaptador de interfaz de usuario, esto podría ser un controlador y presentador que transforme los datos para una vista web. La clave es asegurar que el núcleo nunca importa estos adaptadores directamente.
Paso 4: Limpiar todo juntos en la capa marco
Usar la inyección de dependencia, ya sea a través de un contenedor, una raíz de composición o cableado manual, para conectar los adaptadores al núcleo al inicio. Esta es la responsabilidad de la capa más externa. Por ejemplo, en una aplicación web típica, el punto de entrada principal crea el adaptador de base, el caso de uso y el controlador, luego comienza el servidor. El núcleo permanece oblicuo a estas clases de hormigón.
Paso 5: Aplicar Refactorización Continua
La arquitectura limpia no es un esfuerzo único. A medida que agrega características, comprueba continuamente que el nuevo código no viola la regla de dependencia. Usa herramientas para hacer cumplir límites arquitectónicos (por ejemplo, ArchUnit para Java, o PHPStan con reglas personalizadas para PHP). Extrae la lógica duplicada regularmente en casos de uso y entidades, y empuja código específico marco hacia fuera.
Pitfalls comunes para evitar
- Proyectos pequeños de ingeniería: La arquitectura limpia añade indirectidad. Para una sencilla aplicación CRUD con un solo caso de uso y sin cambios esperados, la sobrecarga puede no valer la pena. Usa tu juicio.
- Código marco de depuración en el núcleo: Es sorprendentemente fácil importar una utilidad marco fuera de conveniencia. Por ejemplo, usando una anotación de ORM en una clase de entidad. Siempre ejecute su módulo central como una biblioteca independiente primero para verificar que no tiene dependencias externas.
- Crear demasiadas interfaces prematuramente: No necesitas una interfaz para cada clase. Sólo abstracto lo que esperas variar. Comience con los principales límites externos (database, UI, sistema de archivos) y generalice más adelante si es necesario.
- Ignorar los límites de manejo de errores: Cómo se lanzan excepciones y se capturan a través de los límites de capas requiere un diseño cuidadoso. Las capas internas deben lanzar excepciones empresariales que son significativas para el núcleo. Los adaptadores externos convierten estos en errores específicos de marco (por ejemplo, HTTP 500) sin el núcleo que se entera del protocolo HTTP.
Ejemplo en el mundo real: un sistema de procesamiento de pedidos simple
Considere una aplicación de comercio electrónico que necesita para hacer un pedido. En un enfoque de arquitectura limpio:
- Entidades: , ], con reglas de negocio como "un orden debe tener al menos un artículo" y "la acción de un producto no puede ser negativa".
- Use Case:] recibe una solicitud que contiene el ID del cliente y la lista de productos. Llama la interfaz para guardar el orden y la para actualizar el stock. También puede llamar una interfaz para alertar al cliente.
- Adaptadores de interfaz: A extrae datos de la solicitud HTTP, llama el caso de uso, y luego un transforma el resultado en una respuesta JSON. A implementa utilizando SQL. An implementa [a API de terceros a .
- Frameworks and Drivers: La raíz de composición establece un servidor web, inicializa la conexión de la base de datos y conecta todas las dependencias juntas. El marco web (por ejemplo, Express.js o Spring Boot) sólo aparece en este anillo exterior.
Si más tarde decide cambiar de PostgreSQL a MongoDB, sólo necesita escribir un nuevo y actualizar la raíz de la composición. El caso de uso y las entidades permanecen intactas. Si desea agregar un nuevo canal de notificación como SMS, cree otro adaptador y regístrelo, de nuevo sin alterar el núcleo.
¿Cuándo debe adoptar arquitectura limpia?
La arquitectura limpia no es una bala de plata. Es más valioso en proyectos con una complejidad moderada a alta, una larga vida esperada, o un dominio de negocios que es central para el éxito de la empresa. Considere la adopción cuando:
- Preves cambios frecuentes en las reglas de negocio.
- El sistema debe integrarse con múltiples bases de datos o servicios externos que puedan cambiar.
- Usted tiene un equipo de desarrolladores que necesitan trabajar en paralelo.
- Usted está construyendo sistemas que sirven a múltiples interfaz de usuario cliente (web, móvil, escritorio) del mismo backend.
Por otro lado, para prototipos pequeños, scripts one-off, o proyectos con un ciclo de vida muy corto, una arquitectura más simple (como una estructura plana MVC) puede ser más pragmática. Siempre puede refactor hacia la arquitectura limpia mientras el proyecto crece.
Conclusión
La arquitectura limpia es un enfoque probado para crear bases de datos que siguen siendo sostenibles, testables y adaptables durante años de desarrollo. Al aplicar la regla de dependencia y separar las preocupaciones en capas distintas, los desarrolladores pueden insular la lógica de negocio central de la inevitable laguna de tecnologías externas. La inversión inicial en diseñar interfaces y organizar códigos paga cuando usted necesita añadir características, cambiar bases de datos, o a bordo de nuevos miembros de equipo.
Para más información sobre el modelado de dominios y la arquitectura limpia en lenguajes de programación específicos, puede referirse a ] Comunidad de Diseño Dominio] o al artículo de arquitectura explícita de Herberto Graça que une varios patrones.