La acusación de waterfall, y qué la responde

Enterate del próximo post
Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.

Un mail cuando publico algo nuevo. Sin spam y te podés dar de baja cuando quieras.
El post anterior cerró señalando la crítica más filosa que recibe Spec Driven Development: escribir un documento antes de tocar código es, dicho sin vueltas, volver al desarrollo en cascada que la industria pasó dos décadas desarmando. No es una objeción de mala fe ni un espantapájaros fácil de tirar abajo: apunta a algo real, y la única forma honesta de responderla es tomarla en serio, no descartarla por asociación de palabras.
El desarrollo en cascada organiza un proyecto en fases secuenciales, requisitos, diseño, implementación, pruebas, donde cada fase se da por cerrada antes de empezar la siguiente. Su problema documentado no es que existan documentos: es que una decisión tomada en la fase de requisitos recién se pone a prueba contra código real varias fases después, a veces meses más tarde, cuando cambiarla ya cuesta mucho más que cuando se escribió. Para cuando el sistema corre por primera vez, buena parte de lo que el documento de requisitos asumía ya cambió, sin que nadie lo haya notado a tiempo.
La acusación contra SDD suena así: pedirle a alguien que escriba una especificación antes de tocar código es la misma apuesta que hacía la fase de requisitos de cascada, con otro nombre. Si el problema de cascada nunca fue escribir documentos sino comprobar tarde, un método que empieza escribiendo un documento hereda el mismo riesgo, por más ordenado que quede ese documento por dentro.
La respuesta honesta no niega la premisa: niega que la unidad de trabajo sea la misma. Cascada especifica el proyecto entero antes de escribir la primera línea de código de cualquiera de sus partes. Lo que esta serie viene mostrando desde el primer post especifica una funcionalidad por vez, guardar un artículo y nada más que eso, y esa funcionalidad se puede implementar y poner a prueba contra código real el mismo día en que se escribió su spec. La diferencia no está en si hay documento antes del código: la hay en las dos formas. Está en cuánto tiempo pasa entre escribir una decisión y comprobarla contra algo que corre de verdad. Ese lazo, no la presencia de un documento, es lo que cascada estiraba a meses y lo que una especificación por funcionalidad puede cerrar en horas.
La Bitácora de lecturas ya tiene, entre los dos posts anteriores, una especificación con intención, contrato y una implementación de referencia, todo para una única funcionalidad, guardar un artículo. Nada de eso tocó ninguna de las otras funcionalidades que el proyecto va a necesitar más adelante: etiquetar un artículo, marcarlo como leído, armar el resumen semanal. Cascada hubiera exigido resolver las cuatro antes de escribir la primera línea de código de cualquiera. Acá alcanza con revisar lo que ya se escribió sobre esta única funcionalidad para ver, en los hechos y no en la promesa, qué tan corto fue ese lazo.
Mismo problema estructural que resolvió el post anterior: este post no agrega ningún paso nuevo al método, así que no tiene, en principio, ningún artefacto propio que producir. La salida es la misma que ya funcionó ahí, tomar el artefacto que la Bitácora ya tiene y agregarle una lente, sin inventar uno nuevo, esta vez sumando a guardar-articulo.md una sección que hace explícito algo que hasta ahora quedaba implícito: el alcance exacto de lo que este documento cubre y lo que deja afuera.
## Alcance
Este documento especifica una única funcionalidad: guardar un artículo a
partir de su URL. No dice nada sobre etiquetar artículos, marcarlos como
leídos ni armar un resumen semanal: son funcionalidades distintas, con
su propia especificación cuando llegue el momento de escribirlas.
Esta funcionalidad se empezó a especificar el mismo día en que se
implementó, no antes: no existe una fase previa de "especificar todo el
proyecto" que este documento venga a cerrar.La decisión menos obvia no es qué agregar, es qué dejar fuera a propósito. Sería más fácil, ya que de todos modos hay que volver a este mismo proyecto en los próximos posts, adelantar unas líneas sobre etiquetas o sobre el resumen semanal mientras se está escribiendo sobre la Bitácora. Hacerlo sería exactamente el error que este post viene marcando: convertir la especificación de una funcionalidad en el borrador de la especificación de todo el sistema, aunque sea de a poco.
La alternativa, especificar la Bitácora entera antes de implementar cualquiera de sus partes, no es hipotética: es, literalmente, la fase de requisitos de cascada aplicada a este mismo proyecto. Antes de escribir una sola línea de código, alguien tendría que decidir cómo se guardan los artículos, cómo se etiquetan, qué separa "leído" de "archivado", y cómo se arma un resumen semanal a partir de todo lo anterior, cuatro decisiones entrelazadas, ninguna puesta a prueba contra código real hasta que las cuatro estén cerradas.
El costo no es solo el tiempo que tarda escribir las cuatro specs antes de empezar. Es que una decisión de la primera, por ejemplo, si una URL se compara ignorando mayúsculas, puede resultar equivocada recién cuando se implementa la tercera, la de etiquetas, al descubrir que dos artículos que deberían compartir etiqueta quedaron separados por esa misma normalización. Con cascada, corregir eso implica revisar una especificación que ya se dio por cerrada semanas atrás, y que otras tres specs ya asumieron como válida. Con una especificación por funcionalidad, ese mismo error se hubiera visto el mismo día en que se implementó guardar, contra el único código que existía en ese momento.
Esto no vuelve a SDD inmune a la crítica de cascada: la vuelve dependiente de sostener el lazo corto. Nada impide escribir, funcionalidad por funcionalidad, una especificación que igual tarda semanas en confrontarse con código real, por ejemplo, si las cuatro specs de la Bitácora se escriben todas seguidas antes de implementar la primera. En ese caso el documento queda dividido en partes más chicas, pero el lazo de realimentación vuelve a ser tan largo como el de cascada, y la crítica vuelve a tener razón. Ese caso, con su costo medido, no solo argumentado, es tema de un post más adelante en esta misma serie, cuando el proyecto avance lo suficiente como para tener números reales que mostrar.
La acusación de waterfall confunde dos cosas que parecen la misma: escribir un documento antes de código, y estirar el lazo entre una decisión y su comprobación. La primera es indistinguible entre los dos métodos. La segunda es la que de verdad los separa.
Con esta funcionalidad ya justificada como unidad de trabajo, el próximo post de la serie entra al primer bloque completo: qué partes tiene que tener la especificación de una funcionalidad para que ese lazo corto funcione en la práctica, y no solo en la promesa de este post.