- En el desarrollo de software, es difícil pasar directamente de un documento de diseño a un PR limpio; como las suposiciones suelen tambalearse durante la codificación real, puede ser más rápido explorar el diseño con código desechable
- Se propone un flujo en el que se crea un prototipo o prueba de concepto en un draft PR que no se va a fusionar, se recibe feedback temprano para alinear el enfoque y luego se conserva como registro de las ideas de diseño
- La premisa de este enfoque es la madurez organizacional para descartar con decisión la primera solución; la disposición a implementar el mismo problema de 2 o 3 formas distintas se considera una señal de seniority
- Un PR se convierte en documentación descubrible que contiene la intención de implementación y la discusión de un momento específico, mientras que un documento de diseño, si no se actualiza con frecuencia, puede convertirse fácilmente en “undead documentation”, desalineada con la realidad
- Los documentos de diseño siguen siendo necesarios para ordenar el feedback de múltiples stakeholders, como documentos North Star de largo plazo, para ideas iniciales que aún son difíciles de codificar, o en organizaciones donde existe el riesgo de que un prototipo termine desplegándose tal cual
Explorar el diseño con Throwaway PR
- El flujo de desarrollo ideal se parece a escribir un documento de diseño, fusionar pequeños PR uno tras otro para lanzar la funcionalidad y mantener limpio el historial de Git
- En la práctica, muchas veces las suposiciones del documento de diseño recién se tambalean después de empezar a codificar, y hay que volver a decidir en qué orden lanzar
- Por eso, puede ser más eficiente crear primero un gran experimento de código y, con base en sus resultados, armar el plan real
-
Procedimiento propuesto
- Implementar un prototipo o prueba de concepto como un draft PR que no se pretende fusionar
- Obtener alineación de dirección con una mirada temprana de otras personas sobre una gran refactorización o el enfoque de una funcionalidad
- Documentar el enfoque dentro del draft PR para dejarlo como registro histórico de las ideas de diseño
- Estar preparado para descartar el draft PR completo lo antes posible
- Extraer gradualmente del draft PR PRs que sí puedan desplegarse, dividiéndolo durante aproximadamente una semana en PRs limpios para despliegue
- Al organizar cada PR por etapas, ir cerrando gradualmente las brechas de pruebas y robustez
-
Condiciones del equipo que requiere este enfoque
- La condición más importante es la madurez para descartar la primera idea que uno codificó
- Sentirse cómodo codificando el mismo problema de 2 o 3 formas distintas puede verse como una señal importante de seniority
- La entrega de valor no está en la cantidad de líneas de código que llegan a producción, sino en el conocimiento que obtiene la organización
- Si se logra alineación temprana en las partes importantes, el prototipado posterior no termina siendo un simple desperdicio
- Hay que estar lo bastante familiarizado con la base de código como para conectar rápidamente sus partes centrales; el personal senior necesita ese nivel de comodidad
- Este enfoque puede aplicarse no solo a nivel individual, sino también a nivel de equipo
Documentación en PR y rol real de los documentos de diseño
- Un PR es una de las formas de documentación útiles para desarrolladores
- Es uno de los primeros lugares donde buscar para entender por qué una implementación quedó de cierta manera
- No pretende reflejar el estado actual, sino que queda como un artefacto histórico que captura el estado de un momento específico
- Si los documentos de diseño no se mantienen actualizados con frecuencia, es fácil que se conviertan en undead documentation que refleja una realidad obsoleta
- Un prototipo encaja con “mostrar en vez de contar”, y cuando se busca generar un cambio, el código puede ser más efectivo que la documentación
- Sin embargo, en organizaciones sin disciplina, existe el riesgo de que un prototipo se reciba como una “respuesta” y no como una “pregunta”
- La intención original se acerca más a “¿deberíamos hacer esto o deberíamos hacer otra cosa?”
- Si la organización lo interpreta como “hay que hacer esto”, aparecen problemas
-
Casos en los que un documento de diseño sigue siendo lo adecuado
- Es útil cuando hay que ordenar y conservar el feedback de múltiples stakeholders, gerentes y equipos externos
- Puede ser difícil manejar ese tipo de colaboración solo con GitHub
- Si la idea es demasiado conceptual y de largo plazo como para codificarla de inmediato, cierta clase de documento North Star ayuda
- Es útil cuando expresarlo por escrito es más eficiente que un primer borrador de código, o cuando todavía no hubo suficiente onboarding en la base de código y se quiere dejar un borrador para recibir feedback
- Si una empresa impulsa el despliegue a producción de inmediato, sin la disciplina para descartar la primera solución, el prototipo puede quedar fijado tal cual como la “solución”
- En organizaciones donde al personal junior le resulta difícil cuestionar la implementación de una idea de un desarrollador senior, puede hacer falta un artefacto más blando que permita hacer preguntas con mayor seguridad
-
Casos en los que los documentos de diseño se usan por malas razones
- Pueden convertirse en un medio para ralentizar el proceso en equipos con poca disciplina o poca experiencia
- Aunque se usen con fines de documentación, por lo general se vuelven obsoletos rápidamente
- Es difícil responder de antemano todas las preguntas de diseño, y los problemas reales recién aparecen después de escribir el código
- Si el equipo puede tener suficiente disciplina, aprender hackeando puede ser más eficiente que el “diseño”
1 comentarios
Opiniones de Hacker News
A esto se le llama prototipado; es una parte valiosa del proceso de diseño, y algunas personas también lo llaman “pathfinding”.
Todas estas cosas son insumos para el diseño, pero sigue siendo necesario un diseño del tamaño adecuado. Si no, solo estás construyendo sobre la marcha. Hay que definir cuál es el problema que se quiere resolver y cuál es la solución. A veces basta con un documento de 1 página sin revisión formal, y a veces hace falta un documento de varias páginas con semanas de revisión e iteraciones de feedback.
No lo olvides: “unas semanas de programación pueden ahorrarte unas horas de planificación” ;)
De hecho, muchas más veces vi lo contrario. La gente planifica y planifica, hasta que el plan no solo deja de tener sentido, sino que empieza a perjudicar activamente la productividad.
Unas semanas de programación pueden ahorrarte unas horas de planificación, pero unas semanas de planificación también pueden desperdiciarse. En papel es fácil escribir cosas que no tienen sentido o son imposibles. Por ejemplo: “pintar una flota de unicornios de un color medio triste”.
Idealmente, el diseño y el prototipo deberían evolucionar juntos, en una espiral como la doble hélice del ADN, donde la iteración de un lado impulsa la siguiente iteración del otro. La gran ventaja de inclinarse hacia crear prototipos es que, al terminar una ronda, queda software que realmente hace algo. Al terminar una ronda de diseño, en la práctica no queda gran cosa.
Y aun en la etapa de implementación hay que seguir priorizando que el código sea descartable. Cuanto más fácil sea borrarlo, mejor.
Pero la ingeniería de software sin documentos de diseño ni ningún tipo de especificación, por más concisa que sea, no es ingeniería; se parece más a construir una casa en un árbol.
Cuanto mayores sean la escala y la importancia del proyecto, más rápido empezarán a aparecer los problemas y la deuda técnica.
Escribir es realmente útil para explorar el espacio del problema.
Muchas veces pensé que entendía bien un problema, pero al empezar a escribirlo surgieron preguntas nuevas e importantes. Esas cosas suelen verse mejor desde una perspectiva más abstracta, o tal vez no aparecen en los primeros hitos de lanzamiento.
Me acuerdo de un mentor que tuve al inicio de mi carrera. Había diseñado a posteriori una configuración active/active para un gateway de pagos y, al abrir Lucidchart, dijo: “este diagrama representa 6 meses de mi vida”.
No siempre es necesario ni útil, pero cuando lo es, unos días de planificación pueden ahorrar semanas de programación.
Podía anticipar con mucha anticipación dónde iban a surgir problemas, así que los proyectos siempre salían fluidos. Cuando veía un problema o incertidumbre, modelaba solo esa parte y luego volvía a la pizarra para continuar.
Como analogía, era como planear un viaje en auto con un mapa. Hoy los documentos de diseño marcan el camino y enseguida se ponen a manejar, mientras que el mapa en la pizarra de ese jefe “planificaba de más”: dónde cargar combustible, horarios de las atracciones, documentos para cruzar fronteras, presupuesto total, kit de emergencia, Plan A y Plan B.
Era tremendamente aburrido, pero mucho mejor que el código descartable. Ahora, no planificar de más me parece perezoso.
Claro que es cierto eso de que “todos tienen un plan hasta que reciben un golpe”, pero eso aplica a la guerra, la política y las negociaciones, no a programar.
Al final, un buen PR también contiene bastante texto y produce el mismo efecto. Creo que un PR en borrador bien documentado es mejor que una propuesta de diseño pura. Porque si solo escribes texto, olvidas restricciones importantes que solo se te ocurren cuando estás dentro del código.
-- Dick Guindon
El mayor problema que tuve con los documentos de diseño es que nadie los lee. Incluso cuando el empleador los exige.
El mayor problema que tuve con el prototipado es que la gente lo ve como “código de lanzamiento” y te obliga a usarlo como código final.
Por eso lo que mejor me funcionó fue un enfoque mixto. Dedico bastante tiempo a planificar y documentar, básicamente para mí mismo, y escribo código de prototipo con calidad de lanzamiento para que, más adelante, pueda usarse sin problema en el producto final.
El documento de diseño termina siendo un montón de notas crudas que nadie salvo el autor entiende bien, y la gente empieza a temer leer esas notas.
Pero si le dices al autor del documento de diseño que esto es como un trabajo final de la escuela que será calificado, después de reescribirlo varias veces el texto puede mejorar bastante. El síntoma es el mismo que con el prototipado: la gente escribe documentos de diseño con calidad de borrador y espera que mágicamente se conviertan en buen texto para una audiencia más amplia. Así como el código prototipo necesita varias refactorizaciones, un documento de diseño necesita varias rondas de edición.
Para evitar renovar el contrato, había que construir y lanzar algo antes de la fecha límite, y ese contrato iba a costar millones de dólares. Pero nos dimos cuenta de que, con los recursos y el enfoque planeados, no llegaríamos a tiempo
Así que obtuve aprobación para crear rápidamente una versión temporal, parcial y no óptima, y gracias a eso pudimos despegar a tiempo
Eso nos permitió volar por un tiempo mientras otras personas terminaban una versión permanente y bien hecha de esa parte del ala
De hecho, durante el vuelo también descubrimos requisitos que faltaban en el diseño original. Eso retrasó el release de producción de la versión correcta, pero pude agregarlos rápido a mi versión hackeada y mantener el vuelo
Mi versión hackeada también cumple el rol de herramienta de soporte de producción. Cuando la versión permanente tiene un bug y hay que detenerla, también sirve como ruta alternativa. Es un hack parcial e incompleto, pero tiene sus ventajas
También hubo quien se quejó de que el lenguaje usado era menos común. Pero hay que recordar que, con los recursos y el enfoque existentes, ni siquiera habríamos podido despegar
Para cumplir con la fecha límite habríamos necesitado más desarrolladores, o desarrolladores más rápidos, en el lenguaje preferido. Si alguien del personal actual, incluyéndome, hubiera tenido el tiempo y la capacidad para ser tan productivo en el lenguaje preferido como yo lo fui con mi hack en un lenguaje minoritario, se le habría asignado crear la solución permanente a tiempo. Esa opción no existía
En todo caso, si ya existe una herramienta de soporte de producción, también es un lugar donde las funcionalidades prototipo pueden quedarse por un tiempo
Es otro artículo de opinión, pero no tiene datos ni siquiera ejemplos concretos
Sé que todos los ingenieros de software tienen opiniones fuertes, pero este es un argumento débil. Si crees que tu trabajo consiste en escribir mucho código para ver qué funciona, pronto te reemplazará GPT. Porque puede hacerlo más rápido y más barato. La parte difícil siempre está en lograr consenso sobre qué hay que construir, y no puedes escapar de ese problema programando
Si los requisitos están claros y también está claro para todos qué voy a entregar, no hace falta. Se puede pasar directo al prototipado. Pero en proyectos serios eso rara vez ocurre. Siempre hay incógnitas desconocidas que hay que extraer de los stakeholders, y el análisis técnico es una buena forma de lograrlo
Los rectángulos y las líneas punteadas tienen límites. Cuando estás alejado del código real, olvidas las restricciones reales. Las cosas que de verdad te frenan no aparecen en Google Docs. En mi experiencia, llegar más lejos es decir “esto es lo que tengo en mente” y señalar un PR en borrador
Y sí, es 100% una opinión. Es un blog personal, no un paper revisado por pares :) No pasa nada si me equivoco
Si no hay algo tangible como el código para anclar la conversación, las discusiones sobre diseños abstractos terminan convirtiéndose en debates sin conclusión del tipo “mi cuerda imaginaria es más larga que tu cuerda imaginaria”
En mi experiencia, el feedback sobre código y el feedback sobre diseño son de tipos enormemente distintos
Un documento de diseño induce preguntas de “por qué” que hacen que todos piensen en el espacio del problema. Por ejemplo, permite comentarios como “¿por qué proponen un servidor web en Rust si en la empresa todavía no hay nadie con soltura en Rust?”
Esas preguntas sutiles son mucho más difíciles de plantear una vez que el prototipo empieza a funcionar. Es fácil que se convierta en “¿por qué importa la experiencia del equipo? ¡Mira qué bien corre! Si no nos bloquean, podemos pulir el prototipo y llevarlo a producción en una semana”
Especialmente cuando se revisa solo el diseño y no código funcionando
Imaginamos que el trabajo de software sigue un flujo limpio y ordenado
Escribes un documento de diseño, haces pequeños cambios incrementales para lanzar la funcionalidad en un PR, y el historial de Git queda limpio y ordenado. Parece un avance constante
¿Quién se lo imagina así? ¿Profesores que enseñan clases de ingeniería de software?
Esto me recuerda a quienes creen que la prosa, los ensayos, los cuentos, las novelas, etc., se escriben haciendo un esquema y luego “rellenándolo” con prosa. Como si en el proceso no hubiera ningún descubrimiento que obligara a reescribir o reestructurar el documento. Nadie escribe así. Los borradores siempre son pésimos, y casi toda buena escritura es el resultado de una revisión importante
Escribir código se parece mucho más a escribir que a construir una casa o un puente
Seguir la nueva lógica línea por línea y mirar variables y memoria realmente ayuda a mejorar el código. Descubro cosas como “ah, esta variable local no hace falta”, “aquí debería agregar una variable temporal para que sea más fácil depurar”, “este código se comporta raro si la colección que itera está vacía”
No importa la edad que tengas ni cuánto código hayas escrito: al depurar código nuevo siempre descubres algo nuevo. Se podría comparar con un escritor que, después de escribir un borrador, lo relee o lo lee en voz alta para sí mismo o para otra persona
Me gusta mucho este proceso de registrar las decisiones de diseño como un hilo de comentarios en curso, en lugar de intentar formalizarlas en un único documento
Yo uso issues de GitHub de esta manera, pero funcionalmente es lo mismo que usar un PR. Un PR es, en la práctica, un issue de GitHub con una rama de código adjunta
Escribí más sobre mi forma de hacerlo aquí: https://simonwillison.net/2022/Jan/12/how-i-build-a-feature/...
En otras palabras, ¿cómo resumes ese hilo en un documento final?
No creo que ambas cosas sean mutuamente excluyentes.
Un documento de diseño es un concepto más amplio, y el objetivo es la comunicación.
A veces hay que transmitir las cosas de una forma que no sea código. Se necesitan diagramas, imágenes, texto, etc.
Para alguien que no es el autor o que no está muy familiarizado con el código, es muy difícil entender los cambios de un vistazo. Para que quien lee pueda construir rápidamente el modelo mental correcto y entender el cambio en su contexto, se necesitan explicaciones y documentación de alto nivel.
Si puedes ver un diff de 1000 líneas y decir con precisión qué hace y, más importante aún, qué impacto tiene aguas arriba y aguas abajo, entonces estás mintiendo o trabajas en un entorno tan perfectamente cerrado y verificable que realmente te envidio.
Un documento de diseño ayuda a reducir a 2 o 3 la cantidad de prototipos entre las opciones posibles. Es especialmente útil cuando se explora cómo agregar algo completamente nuevo.
Siento que mostrar es mejor que contar, pero alguien que acaba de sumarse lo entiende más fácilmente mediante un documento de diseño que mediante el código.