Cómo se aplican los principios SOLID en arquitecturas modernas

La evolución del desarrollo de software ha traído consigo nuevas formas de estructurar sistemas: desde arquitecturas monolíticas limpias hasta entornos distribuidos con microservicios, eventos y dominios altamente desacoplados. En todos estos enfoques, los principios SOLID siguen siendo una brújula técnica para lograr modularidad, flexibilidad y mantenibilidad.

Aunque originalmente fueron concebidos para el diseño orientado a objetos, los principios SOLID tienen implicaciones directas en la arquitectura de sistemas completos. Este artículo explora cómo se aplican estos principios en distintas arquitecturas modernas, y por qué siguen siendo esenciales incluso más allá del nivel del código.

 

Arquitectura Limpia (Clean Architecture)

 

Clean Architecture propone una separación estricta entre el núcleo del dominio (que no debe conocer ningún detalle de infraestructura) y las capas externas (como bases de datos, frameworks web o mensajerías).

 

SRP – Separación clara de responsabilidades por capa

Cada clase y capa tiene una única responsabilidad. Los casos de uso no deben hacer validaciones de entrada, ni persistencia, ni rendering. Por ejemplo, un RegistrarUsuarioUseCase solo coordina lógica de negocio; la validación se delega a otra clase.

OCP – Nuevas funcionalidades sin romper el núcleo

Agregar un nuevo canal de notificación o motor de base de datos solo requiere extender un adaptador, sin tocar la lógica de negocio central.

LSP – Implementaciones intercambiables

Los adaptadores de entrada o salida pueden ser sustituidos sin romper el flujo (por ejemplo, un nuevo sistema de almacenamiento que implementa la misma interfaz RepositorioDeUsuarios).

ISP – Interfaces por caso de uso

Cada caso de uso define interfaces específicas. En vez de tener un RepositorioGeneral, cada agregado tiene su propia interfaz minimalista, lo que evita acoplamientos innecesarios.

DIP – Dependencias invertidas desde el dominio

La lógica del negocio define las interfaces, y los detalles las implementan. Esto significa que el dominio no depende de frameworks, motores de base de datos o controladores HTTP.

 

Microservicios

 

En arquitecturas de microservicios, el sistema se divide en servicios pequeños, autónomos y desplegables independientemente, cada uno centrado en un único dominio.

SRP – Cada servicio con un solo propósito

Un microservicio bien diseñado representa una única capacidad de negocio. Por ejemplo, ServicioDePagos no se encarga de GestiónDeUsuarios.

OCP – Evolución sin modificar lo existente

Los microservicios pueden extenderse agregando nuevos endpoints o eventos, sin modificar la lógica actual, permitiendo una evolución segura.

LSP – Compatibilidad con consumidores

Una nueva versión del servicio debe ser compatible con los contratos anteriores. Si se rompe la capacidad de sustitución, los consumidores fallarán.

ISP – APIs específicas por consumidor

En vez de exponer una API genérica para todos, se puede construir una fachada personalizada o usar GraphQL para que cada cliente consuma lo necesario.

DIP – Servicios internos desacoplados por abstracciones

Incluso dentro de un microservicio, se inyectan puertos (interfaces) en lugar de depender directamente de bases de datos, colas o integraciones externas.

 

Domain-Driven Design (DDD)

 

DDD promueve el modelado explícito del dominio a través de entidades, agregados, servicios de dominio, repositorios y contexto delimitado.

SRP – Agregados autocontenidos

Cada agregado encapsula su consistencia y lógica. Por ejemplo, un Pedido tiene su lógica de cambio de estado, sin depender de lógica externa.

OCP – Nuevas reglas sin romper agregados

Las reglas de negocio pueden extenderse agregando nuevos servicios de dominio que operan sobre los agregados sin modificar su estructura base.

LSP – Sustitución coherente de implementaciones

Repositorios, servicios de validación o políticas de negocio pueden cambiar manteniendo la interfaz esperada. Esto es fundamental cuando se hacen pruebas o se alternan reglas entre contextos.

ISP – Contratos por agregado

Los consumidores externos o internos del dominio interactúan con interfaces reducidas: IPedidoRepository, ICalculadorDeImpuestos, etc., en lugar de una API genérica.

DIP – Aislando el dominio del entorno

El dominio no depende de detalles como bases de datos o frameworks. Todo se conecta a través de interfaces, y los detalles se resuelven desde el exterior.

 

Arquitectura basada en eventos

 

Los sistemas orientados a eventos comunican sus componentes a través de mensajes asincrónicos, permitiendo bajo acoplamiento y alta escalabilidad.

SRP – Manejadores por tipo de evento

Cada clase que consume eventos está especializada en un solo propósito, como ManejadorEventoCompraCreada.

OCP – Nuevos consumidores sin romper emisores

Se pueden agregar nuevos suscriptores a un evento sin modificar el código del emisor original.

LSP – Sustitución de consumidores

Un consumidor de eventos puede ser reemplazado por otra implementación (por ejemplo, una versión que hace reintentos o logging) sin cambiar la semántica del flujo.

ISP – Contratos de eventos reducidos

Los eventos contienen solo los datos mínimos necesarios para ser procesados. Los consumidores no deben depender de campos innecesarios que podrían desaparecer.

DIP – Productores y consumidores desacoplados

Ambos lados interactúan a través de un contrato (como un schema Avro o JSON), pero no conocen la implementación del otro extremo. Esto permite escalar e integrar distintos lenguajes o tecnologías.

 

Arquitecturas modulares o monolíticas limpias

 

Incluso en sistemas monolíticos, SOLID permite crear capas y módulos independientes que pueden evolucionar y mantenerse con facilidad.

SRP – Módulos por responsabilidad funcional

Cada módulo (por ejemplo, usuarios, facturación, reportes) se aísla en código y lógica. Esto facilita la prueba y el mantenimiento.

OCP – Agregar funcionalidades sin alterar el core

Puedes extender comportamientos creando nuevos controladores, servicios o eventos sin tocar el núcleo del sistema.

LSP – Sustitución de implementaciones internas

Permite cambiar servicios de almacenamiento, lógica o validaciones sin alterar el código que los usa.

ISP – Interfaces internas bien definidas

Los distintos módulos se comunican a través de contratos específicos, sin exponer su implementación interna.

DIP – Inversión de dependencias por capas

El core del sistema no depende de frameworks, solo de contratos definidos internamente. Los detalles como bases de datos, autenticación o redes se inyectan desde afuera.

 

Conclusión

 

Los principios SOLID no son exclusivos del diseño de clases orientadas a objetos. Son una guía atemporal para construir sistemas que sobreviven al cambio, escalan sin dolor y mantienen la coherencia entre múltiples equipos y tecnologías.

En cada arquitectura moderna, SOLID cumple un rol clave:

  • En Clean Architecture, permite separar detalles del dominio.
  • En Microservicios, ayuda a mantener la autonomía y claridad.
  • En DDD, refuerza el modelado rico y desacoplado.
  • En event-driven, sostiene el bajo acoplamiento entre componentes.
  • En monolitos modulares, ayuda a mantener orden y escalabilidad.

La aplicación consciente de estos principios no es una receta rígida, sino una práctica estratégica para crear software sostenible y alineado con la evolución del negocio.

Whatsapp Mentores Tech