Antipatrones de System Design y cómo evitarlos | Nicolás Garzón
Un antipatrón no es una práctica “prohibida”. Es una solución que parece razonable, se repite y falla porque ignora contexto, evidencia o consecuencias.
Reconocer antipatrones permite detener decisiones que generan complejidad sin reducir riesgo. La alternativa correcta no es otra receta universal, sino volver a drivers, restricciones y evidencia.
Texto
Copiar “Usaremos microservicios, Kafka y Kubernetes”Problema: la tecnología aparece antes del problema, la escala, el equipo y las garantías.
No existe escenario que justifique distribución.
Nadie puede explicar el coste operativo.
Los límites se dibujan por tablas o repositorios.
Define objetivos y restricciones.
Estima carga y fallos relevantes.
Diseña la opción más simple que cumpla.
Conserva una ruta de evolución.
Una restricción tecnológica real sí puede aparecer temprano, pero debe documentarse como restricción.
Diseñar para una escala hipotética crea colas, cachés, particiones y servicios que el equipo todavía no puede operar.
La solución resuelve millones de usuarios inexistentes.
No resuelve el flujo actual ni su adopción.
Cada cambio cruza demasiados sistemas.
Corrección: escala por evidencia, identifica hotspots reales y agrega complejidad de forma reversible.
Texto
Copiar “El sistema debe ser rápido, seguro y escalable.”No existe condición verificable.
Texto
Copiar El 95 % de las búsquedas responde en menos de 300 ms
con 150 solicitudes por segundo
sobre 100 000 productos.“Login, dashboard, productos y reportes” no explica resultados, responsabilidades ni fallos.
Corrección: expresar capacidades, actores, flujos, fuentes de verdad, integraciones y exclusiones.
La plantilla “como, quiero, para” no contiene reglas, errores, datos ni calidad.
Corrección: acompañar con conversación, criterios, reglas y trazabilidad.
“Presionar Guardar” es interacción de interfaz, no objetivo del actor.
Corrección: modelar “Registrar venta”, “Cancelar pedido” o “Aprobar transferencia”.
El diseño parece correcto hasta que existe timeout, duplicado, concurrencia o fallo parcial.
Corrección: para cada flujo incluir:
Alternativas.
Excepciones.
Estado incierto.
Recuperación.
Idempotencia.
Evidencia operativa.
Mezcla usuarios, servicios, clases, bases, regiones y secuencias.
Consecuencia: nadie sabe qué pregunta responde.
Corrección: una vista por audiencia y nivel; Context, Container, Component, Sequence, State o ERD según la pregunta.
Una relación llamada “usa” oculta intención, protocolo, dirección y criticidad.
Texto
Copiar Order API → Inventory
Reserva unidades de forma síncrona por HTTPS
Timeout 300 ms; operación idempotenteCopiar tablas produce entidades anémicas y reglas dispersas.
Corrección: descubrir conceptos, identidad, invariantes y comportamiento antes de decidir persistencia.
User Service, Product Service y OrderLine Service suelen reflejar datos, no capacidades cohesionadas.
Consecuencia: transacciones distribuidas y llamadas excesivas.
Corrección: límites por responsabilidad, reglas y ritmo de cambio; mantener modularidad interna antes de distribuir.
Varios componentes escriben las mismas tablas directamente.
Reglas imposibles de localizar.
Cambios de schema peligrosos.
Acoplamiento oculto.
Corrección: ownership explícito, contratos y acceso controlado. Compartir infraestructura no implica compartir autoridad.
Cache, índice y proyección se actualizan sin estrategia de reconciliación.
Corrección: declarar autoridad, mecanismo de propagación, tolerancia al retraso y reparación.
Texto
Copiar isPaid
isCancelled
isDeliveredPermite combinaciones contradictorias.
Corrección: ciclo de vida explícito, transiciones, guards y efectos.
Retries sin límite multiplican carga y duplican efectos.
Timeout.
Backoff y jitter.
Presupuesto de intentos.
Idempotencia.
Clasificación de errores.
Circuit breaker o cola cuando corresponde.
Muchos sistemas entregan al menos una vez y requieren consumidores idempotentes.
Corrección: definir exactamente qué efecto debe ser único, usar claves, deduplicación, transacción y reconciliación.
Añadir cache antes de medir puede ocultar consultas malas y crear invalidación compleja.
Corrección: perfilar, optimizar acceso, definir freshness y decidir qué ocurre ante miss o datos antiguos.
Se implementa autenticación, pero no autorización por recurso, tenant ni acción.
Corrección: threat modeling, límites de confianza, clasificación de datos, least privilege y pruebas desde el diseño.
Logs sin contexto no explican una solicitud ni el impacto al usuario.
Corrección: SLIs, correlation IDs, métricas de dominio, trazas y alertas accionables.
Tener archivos de backup no demuestra recuperación.
Corrección: ejecutar restore, medir RTO/RPO, validar integridad y documentar procedimiento.
Pesos arbitrarios y puntuaciones sin evidencia producen un ganador matemático falso.
Corrección: criterios ligados a drivers, restricciones eliminatorias, sensibilidad y evidencia.
Un spike omite seguridad, operación y mantenibilidad; una demo exitosa se presenta como producto listo.
Corrección: decidir si es desechable, registrar qué no demuestra y reconstruir garantías antes de producción.
Se escribe después para defender una decisión ya tomada.
Corrección: documentar contexto, alternativas y consecuencias mientras la decisión sigue abierta o al menos preservar honestamente la razón real.
Crear todos los diagramas aunque no reduzcan incertidumbre.
Corrección: cada artefacto debe tener pregunta, audiencia, owner y decisión asociada.
Páginas marcadas como listas no cambian aunque el sistema sí.
Corrección: fuente de verdad, estados, fechas, triggers, ownership y archivo de contenido sustituido.
Una recomendación externa sustituye análisis contextual.
Texto
Copiar driver
→ alternativa
→ consecuencia
→ evidencia
→ decisiónSe elige una solución costosa de operar para un problema aún no demostrado.
Corrección: priorizar decisiones reversibles, POC y medición antes de comprometer arquitectura.
Ante un diseño sospechoso pregunta:
¿Qué problema y métrica lo justifican?
¿Qué restricción obliga a esta complejidad?
¿Qué alternativa más simple se descartó y por qué?
¿Qué fallo se modeló?
¿Cómo se validará?
¿Quién lo operará?
¿Qué ocurre cuando cambie?
El antipatrón suele comenzar con una verdad aplicada fuera de contexto.
Más componentes y documentos no implican mejor diseño.
La ausencia de fallos y operación produce modelos irreales.
La evidencia debe preceder a la complejidad difícil de revertir.
Volver al problema es la principal herramienta de corrección.
¿Cuándo una cache deja de ser optimización y se convierte en fuente de riesgo?
¿Por qué un servicio por tabla aumenta acoplamiento?
¿Qué hace incompleta una POC de rendimiento?
¿Cómo reconocerías un diagrama sin pregunta?
Ver respuestas
Cuando no existe política de freshness, invalidación, autoridad y reparación de datos.
Porque los flujos de negocio cruzan entidades y obligan a llamadas y consistencia distribuida sin límites cohesionados.
Si no usa carga, datos, topología y métricas representativas o ignora operación y seguridad.
Mezcla niveles, tiene flechas genéricas y no permite tomar ni validar una decisión concreta.
Modelo mental completo de System Design integra la ruta correcta para evitar estos atajos.