El conocimiento es el nuevo dinero.
Aprender es la nueva manera en la que inviertes
Acceso Cursos

Cómo las arquitecturas más sencillas me convirtieron en un mejor desarrollador sénior.

Una vez creamos un sistema de pago utilizando microservicios desde el primer día. La idea era crear un sistema que fuera escalable desde el primer día

· 5 min de lectura
Cómo las arquitecturas más sencillas me convirtieron en un mejor desarrollador sénior.

Consejos para diseñar arquitecturas más sencillas pero eficaces

Solía creer que cuantos más recuadros hubiera en el diagrama, mejor era el diseño. Tras años trabajando en grandes sistemas empresariales, aprendí lo contrario.

La mayoría de los sistemas no fallan por falta de herramientas. Fallan porque tienen demasiadas.

A continuación se presentan cinco prácticas arquitectónicas que han cambiado mi forma de pensar sobre el diseño de sistemas.

1. Dividir los sistemas solo cuando sea necesario

Una vez creamos un sistema de pago utilizando microservicios desde el primer día. La idea era crear un sistema que fuera escalable desde el primer día.

Incluso con poco tráfico, cada solicitud de pago genera múltiples llamadas a la red. Un fallo en cualquier servicio provoca que falle todo el pago.

Además, la depuración era un quebradero de cabeza. Era necesario buscar en los registros y coordinar a los equipos.

Además, incluso un simple cambio requiere la implementación en servicios dependientes.

Simplifiquemos esta arquitectura.

Al mantener los límites lógicos y eliminar la separación física, redujimos drásticamente los modos de fallo.

Las implementaciones son ahora más fáciles. La depuración es ahora más rápida.

Cuando surge la necesidad de escalar, podemos extraer uno de los servicios más utilizados y convertirlo en su propio microservicio.

Una arquitectura diseñada para gestionarlo todo suele no gestionar nada bien.

2. Evitar la abstracción excesiva

Heredamos un sistema de gestión de pedidos que era difícil de mantener. Nuestro primer instinto fue limpiarlo añadiendo abstracciones.

Se introdujeron servicios genéricos, repositorios compartidos y clases base para «estandarizar» el comportamiento.

El resultado fue peor que antes.

Para comprender el flujo de pedidos era necesario saltar entre interfaces y clases base. Las reglas de negocio estaban dispersas por todas las capas, lo que encarecía incluso los cambios más sencillos.

La abstracción eliminó la duplicación, pero también eliminó el significado.

Invertimos el enfoque.

En lugar de capas genéricas, hicimos que los flujos de trabajo fueran explícitos. La creación de pedidos, la fijación de precios y el cumplimiento se plasmaron en código concreto.

Quedó algo de duplicación, pero era intencionada y visible. Los cambios se volvieron locales y los fallos se hicieron más fáciles de rastrear.

Los sistemas simples se rompen de forma clara. Los sistemas complejos se rompen de forma misteriosa.

3. Prefiere una arquitectura simple a una inteligente

En un sistema de pago, adoptamos una arquitectura basada en eventos para todo el flujo. Cada paso emitía y consumía eventos.

Parecía elegante en la pizarra. Fue doloroso en la producción.

Deténgase un momento. ¿Ve algún problema evidente en esta arquitectura?

La mayoría de los debates se centraron en el orden de los eventos, los reintentos y el retraso de los consumidores. Ningún servicio era claramente responsable del resultado final de un pedido. Los fallos dejaban los pedidos en estados parciales que requerían una intervención manual.

La arquitectura está optimizada para ofrecer flexibilidad a costa de la claridad.

Sustituimos el flujo totalmente basado en eventos por un servicio de pago sencillo y sincrónico.

Un servicio se encargaba de todo el ciclo de vida del proceso de pago. Validaba el carrito, procesaba el pago y devolvía un resultado final de éxito o fracaso.

Se seguían utilizando eventos, pero solo para efectos secundarios como análisis y notificaciones. El flujo principal del negocio seguía siendo lineal y fácil de entender.

Los fallos ahora eran inmediatos y visibles. Un pedido se completaba o fallaba claramente, nunca quedaba en un estado ambiguo.

Cuando una arquitectura necesita una larga presentación para explicar cómo funciona, es probable que esté haciendo demasiado.

4. No lo vas a necesitar (YAGNI)

El producto tenía un alcance limitado.

Los usuarios enviaban comentarios. Los administradores los revisaban.

Pero la arquitectura era mucho más compleja que eso.

Sobre el papel, el diseño anticipaba el crecimiento. En realidad, se optimizó para un futuro que nunca llegó. Esto también crea muchas complejidades:

  • Múltiples capas arquitectónicas dentro de un único servicio
  • Flujo impulsado por eventos para el envío de comentarios
  • Tablas separadas para comentarios, estado y registros de auditoría
  • Indicadores de características que protegen las funciones inacabadas o no utilizadas

Toda esta complejidad residía en un único servicio. No resolvía ningún problema real. Solo reflejaba suposiciones sobre el futuro.

La arquitectura simplificada se ve así:

Al eliminar las abstracciones, tablas e infraestructura que no se utilizaban, el sistema se volvió autoexplicativo.

La mayoría de los sistemas colapsan bajo el peso de las decisiones tomadas para manejar problemas que nunca llegaron a producirse.

5. Demasiada configuración no siempre es buena

Un sistema interno llevó la flexibilidad demasiado lejos. Casi todos los comportamientos dependían de la configuración.

Las banderas de características, las variables de entorno y los múltiples archivos de configuración influían en la lógica central. La mayoría de los incidentes de producción no fueron causados por defectos en el código, sino por una configuración incorrecta.

En teoría, esto parece flexible, pero tiene muchas complejidades ocultas:

  • Múltiples fuentes de configuración cargadas en tiempo de ejecución
  • Indicadores de características que controlan rutas de ejecución críticas
  • Comportamiento específico del entorno repartido por todo el código base

Para comprender cómo se comportaba el sistema, primero había que comprender cómo se implementaba.

Ahora, veamos la arquitectura simplificada:

Valores predeterminados claros definidos directamente en el código

  • Las marcas de características solo se utilizan para implementaciones temporales
  • Configuración limitada a diferencias genuinas del entorno

Con menos partes móviles, las implementaciones se volvieron más seguras. El comportamiento del sistema se volvió predecible. El código se explicaba por sí mismo.

Cuando la flexibilidad se convierte en el objetivo principal, la claridad suele ser la primera víctima.

Una arquitectura simple no significa un diseño débil. Significa eliminar la complejidad innecesaria para que los sistemas sigan siendo comprensibles a medida que crecen.

Los sistemas sólidos comienzan siendo simples. Su complejidad se gana con el tiempo.

¿Cree que su sistema es innecesariamente complejo? Compártalo en los comentarios o envíe un diagrama. Simplifiquémoslo juntos.

Gracias por leer Código en Casa.
Si esto te a ayudado y te sumo algo Dale un 👏 , compártelo con tu red o dejame un comentario para saber tu opinión.