← Código en el que puedes confiar ETAPA 03 · 34 MIN

Modela estados, no suposiciones

Usa estados y transiciones explícitos para que el comportamiento inválido sea más fácil de detectar.

Abrir en el laboratorio ↗

AL TERMINAR, PODRÁS

  • Modelar una máquina de estados finitos
  • Separar las anotaciones de tipo estáticas de la validación en ejecución
  • Usar composición alrededor de responsabilidades con sentido
Modela los estados que importan. Solo las flechas dibujadas aquí son movimientos válidos.

Descripción del diagrama: queued → running (reservar); running → succeeded (terminar); running → failed (error); failed → queued (reintentar si quedan intentos)

Encuentra los estados que importan

Un trabajo puede estar pendiente, en ejecución, exitoso o fallido.

Esas etiquetas solo sirven cuando las transiciones están definidas. ¿Un trabajo exitoso puede volver a ejecutarse? ¿Un trabajo fallido puede reintentarse?

¿La cancelación aplica al trabajo en ejecución? Dibuja las transiciones permitidas antes de agregar condicionales por todo el código. Cada transición tiene precondiciones y efectos.

Una máquina de estados (state machine) hace visibles los casos que faltan y da a las pruebas (tests) una estructura natural. También evita que varias banderas booleanas representen combinaciones contradictorias, como estar completado y pendiente a la vez.

Deja que el modelo cargue las restricciones

Las dataclasses de Python agrupan campos relacionados, mientras que los enums nombran un conjunto finito de estados.

Las anotaciones de tipo comunican las formas esperadas y ayudan al análisis estático a detectar incoherencias antes de ejecutar. No reemplazan la validación de JSON externo ni de filas de una base de datos. Valida en las fronteras de confianza y mantén suposiciones más fuertes hacia adentro.

Prefiere un modelo cuyos campos tengan un significado claro en cada etapa. Si un objeto gigante tiene decenas de campos opcionales, considera si estados distintos u objetos más pequeños expresarían el ciclo de vida con más precisión.

Compón el comportamiento donde varía

Un worker combina planificación, almacenamiento y ejecución de trabajos.

Pasar estos colaboradores de forma explícita hace visibles sus responsabilidades y permite sustituirlos de forma enfocada en las pruebas. La herencia es útil cuando existe una relación de sustitución genuina, pero una jerarquía profunda suele hacer más difícil encontrar el comportamiento. Elige un patrón porque resuelve un problema con nombre, no porque te resulte familiar.

En Relay, distintos manejadores de trabajos pueden compartir un contrato pequeño de función mientras el almacenamiento y la política de reintentos siguen siendo independientes. El buen diseño reduce la cantidad de hechos que alguien tiene que tener en la cabeza al mismo tiempo.

ERROR FRECUENTE

Agregar un enum no obliga por sí solo a que las transiciones sean válidas. Centraliza las reglas de transición y valida los cambios a través de esa frontera.

INTÉNTALO TÚ

Dibuja la máquina de estados de Relay incluyendo cancelación y reintento. Enumera dos transiciones que deben rechazarse y la evidencia necesaria para autorizar que un trabajo se marque como completado.

COMPROBACIÓN DE RECUERDO / APLICA LA IDEA

Decide en el laboratorio.

El checkpoint de dos preguntas, tus notas y tu progreso guardado están en el laboratorio. Gratis y sin cuenta.

Abrir en el laboratorio ↗

CONÉCTALO CON RELAY

Centraliza las transiciones de los trabajos de Relay y prueba una transición inválida, como avisar que terminó un trabajo que nunca se reservó.

VE A LA FUENTEPython: dataclasses ↗Python: typing ↗Las fuentes están en inglés.