Saltar al contenido

Blog técnico | Termina lo que empiezas

Me encanta empezar proyectos de hobby. Sin embargo, parece que odio terminarlos. La descripción de GitHub de uno de mis proyectos personales de hace más de un año dice «Trabajo en progreso»: Juro que finalmente terminaré este proyecto».

Es emocionante proponerse construir algo nuevo. El impulso inicial es estimulante. La funcionalidad empieza a brotar por todas partes, se progresa, el final está a la vista. Hasta que no lo esté. En algún momento del camino, algo sucede, se pierde el impulso, y el proyecto es abandonado – o el punto final se convierte en una zanahoria que cuelga perpetuamente.

Blog técnico | Termina lo que empiezas
Blog técnico | Termina lo que empiezas

A principios de 2018, en busca de ser un mejor programador, me propuse encontrar la raíz de mi lucha por llevar un proyecto a la meta. En los últimos 11 meses, he llegado a la conclusión de que hay dos culpables. El primero es la falta de equilibrio entre el tiempo dedicado a la planificación, la exploración y la codificación. El segundo es la dificultad de mantenerse centrado en la tarea que se está llevando a cabo. ¿Cómo se pueden abordar estas cuestiones? Propongo una variedad de soluciones, divididas en las tres etapas de un proyecto: explorar, hacer y terminar. En la fase de exploración, se crea una pista para mover el proyecto en la dirección correcta. En la fase de hacer nos mantenemos en esa pista, y en la fase de terminar, llegamos a nuestro destino.

Explorar

Antes de escribir una sola línea de código pulido, es importante dedicar tiempo a explorar el problema, identificar las soluciones y emprender el camino hacia el final. O para dar una analogía, puedes pensar en el código pulido como el borrador final y la fase de exploración como la investigación y el esbozo.

Poco después de mi carrera como ingeniero de software, me dieron las riendas para elegir mi primer proyecto en un nuevo trabajo. Estaba trabajando en un sitio web de fitness y me di cuenta de que las fotos de perfil de nuestros usuarios estaban aplastadas verticalmente, lo que tuvo el desafortunado resultado de hacerlas parecer más grandes de lo que eran en realidad. En mi mente, esto era inaceptable y requería que yo sacara todas las paradas. Sin pensarlo mucho, me lancé al código. Seguramente el problema se resolvería con el perfecto recorte de imagen, construido desde cero. O eso creía.

Tres días después, las imágenes podían ser recortadas, rotadas o escaladas – pero mi código no podía hacer las tres cosas al mismo tiempo sin problemas raros. Entré en pánico y decidí empezar a buscar soluciones prefabricadas para React. Excepto que apenas conocía a React. Otro día y medio después, me detuve, me tomé un descanso y pedí ayuda a mi jefe.

Conozca sus recursos

Me di cuenta de que lo que me había propuesto construir era demasiado ambicioso. Una empresa más grande, con decenas o cientos de ingenieros, podría dedicar más recursos a resolver tal problema. Sin embargo, éramos un equipo de dos ingenieros trabajando en un sitio web apenas salido de su infancia. Durante la autopsia, tuvimos una discusión que se podría resumir en el Manifiesto Ágil Principio de Simplicidad que establece, «El arte de maximizar la cantidad de trabajo no realizado es esencial» [1]. El objetivo más realista y mucho más fácilmente alcanzable fue una solución descubierta después de un corto período de investigación. Nos ahorró mucho tiempo, satisfizo a la mayoría de las fotos de perfil de los usuarios, hizo que el código fuera más sencillo y fácil de mantener, y nos dio tiempo para volver al tema más tarde y centrarnos en otras cuestiones más apremiantes.

Saber lo que estás construyendo

Cuando me propuse construir el cortador de imágenes, me dirigí en la dirección completamente equivocada sin tener en cuenta las múltiples maneras diferentes en que el problema podría haber sido resuelto. Es importante saber lo que podría ser necesario en el viaje para ser hecho. Pasar tiempo investigando alternativas, leyendo artículos, discutiendo el tema, etc. Este proceso le ayudará a darse cuenta de todos los aspectos que entran en una posible solución.

Pruebe las diversas soluciones

Cuando empecé a codificar, cuando creaba nuevas características, empezaba a intentar escribir la solución junto con el resto de mi código totalmente funcional. A veces, entraba en un estado extraño y decidía revertir todos los cambios, ya que preveía más tiempo para arreglar el desastre que acababa de escribir.

Me di cuenta de que mi problema era que no sabía exactamente lo que estaba construyendo. Intentaba escribir un código de producción para resolver un problema que aún no entendía o no sabía cómo sería la solución. En este caso, me pareció que lo mejor era crear una rama o un archivo de raspado separado, establecer un temporizador y empezar a codificar soluciones alternativas a los aspectos del problema. No escribas pruebas, no te preocupes por la calidad del código, ni pases demasiado tiempo codificando; sólo escribe. Cuando el temporizador esté listo, pregúntese «¿Es esto suficiente para tomar una decisión o necesito más tiempo?». Cuando esté satisfecho con su investigación, empiece de nuevo (o mejor aún, escriba las pruebas – más en un rato).

Do

¿Alguna vez te has encontrado en la tarea de resolver algún problema, te has desviado de un poco de refactorización o has resuelto un error menor que habías notado y dos horas más tarde has editado 20 archivos diferentes y ni siquiera puedes recordar lo que te propusiste resolver en primer lugar? He estado allí demasiadas veces. Afortunadamente, siguiendo los consejos que he propuesto, en mi último proyecto personal, sólo una vez hice un commit en el que añadí un montón de código para el que no podía escribir un resumen conciso de sus cambios. (Para los curiosos, el primer commit decía «¿Qué he hecho?» seguido de «…qué he hecho, en serio».)

Establecer metas tangibles y seguirlas

Una vez vi una lista de cosas por hacer que contenía cosas tan bien definidas como «Encontrar un nuevo apartamento». ¿Cómo se hace eso? Tal vez lo mejor sería poner cosas como «Ponerse en contacto con un agente de bienes raíces» y «Revisar un apartamento a la semana».

Lo mismo se aplica a los proyectos de codificación como «añadir una nueva página a la aplicación X». Yo solía saltar y empezar a escribir hasta que la nueva página se implementaba. Excepto que eso implicaba un montón de partes móviles y nunca supe si algún aspecto de la página en la que estaba trabajando estaba realmente terminado. Podría pasar días trabajando en algún script que podría haber sido implementado en minutos con una búsqueda rápida en Google o pasar horas ajustando algunos CSS, nunca haciendo realmente un progreso real. Se siente como un juego interminable de «whack-a-mole» en el que nunca se siente nada hecho, no hay hitos pasados, sólo un comienzo y un final sin nada en medio.

Este método no funciona para tareas más grandes y con el tiempo he pasado a un enfoque más metódico. Continuando con el ejemplo de la nueva página, desgloso las diversas tareas que van a terminar la página y las ordeno de manera que una tarea lleve a la siguiente. Comienzo conectando la página con el resto de la aplicación e imprimiendo «¡Hola Mundo!» en la pantalla. Luego comenzaré a abordar cada sección individual de la página. A veces desgloso las tareas más hasta que puedo buscar el alcance del trabajo requerido para cada una. Por ejemplo, si esta página tiene un formulario de contacto, los pasos que puedo dar incluyen construir la estructura del formulario con HTML, añadir lógica para comprobar las entradas adecuadas con JavaScript, hacerlo bonito con CSS y conectarlo a la API. Cada paso, significa un hito, una tarea completada, y un paso más cerca de ser hecho.

Diseño con Desarrollo Dirigido por Pruebas

Antes de saber lo que era TDD, hice suposiciones basadas en las tres palabras que componen el acrónimo. Creía que la idea era que en lugar de escribir pruebas después de escribir el código, las pruebas se escribirían antes del código. Pero es mucho más que eso.

Tuve un momento aha mientras leía Growing Object-Oriented Software, Guided by Tests que afirma que «TDD convierte las pruebas en una actividad de diseño»[2]. Además, afirma que «escribir una prueba nos obliga primero a aclarar nuestras intenciones, y no empezamos el siguiente trabajo hasta que tengamos una descripción inequívoca de lo que debe hacer»[2]. Al escribir una prueba primero, una prueba que falla ya que no tenemos código, tenemos un indicador de algo en lo que estamos trabajando, una prueba que una vez exitosa, marca nuestro trabajo como hecho.

Sobre esto está la idea de la prueba de doble bucle. La prueba de doble bucle consiste en una prueba de imagen más grande, como «Construir un widget que pueda enviar texto», y dentro de esa prueba hay varias pruebas más pequeñas que conforman las diversas funcionalidades de ese widget. Juntas, las tareas del tamaño de un bocado y sus pruebas asociadas pueden pasar en la búsqueda de hacer pasar la prueba de bucle exterior más grande.

Manténgase enfocado

Como se mencionó en la introducción de esta sección, históricamente he sido notoriamente malo en mantenerme enfocado en la tarea en cuestión. Con el tiempo, he descubierto algunos métodos que me ayudan a mantenerme en el camino.

Queue It

Una solución a esto es que pondré un pedazo de papel (un rastreador de problemas también funciona) y escribiré en qué estoy trabajando. Si veo algún otro código que necesite ser reparado o mejorado, lo anotaré en mi cola y volveré a lo que estaba trabajando. Una vez que termine con el tema actual, puedo decidir si abordar esos temas o rastrearlos en otro lugar para abordarlos en el futuro.

Evitar el arrastre de características

Mantén la pregunta en el fondo de tu mente «¿Es esto en lo que debería estar trabajando ahora mismo?» Si no lo es, ponlo en la cola, o deséchalo.

Cometer la funcionalidad de tamaño de mordida y hacerlo a menudo

Concéntrese en no alejarse nunca de un estado de funcionamiento del código. Incrementar la funcionalidad y confirmarla. Combina esto con una cola y trabaja constantemente para pasar las pruebas.

Terminar

Envolviéndolo

En este punto, debería haber indicadores de que has terminado. Las pruebas están pasando. Las cosas por hacer están siendo tachadas de las listas. ¡Impresionante! Estás acabado.

Pero, ¿funcionan estos métodos?

Mientras intentaba concluir este post me di cuenta de que te preguntarías, «cosas interesantes, ¿te funcionan realmente?» Para responder a esta pregunta, decidí echar un vistazo a mi historia en GitHub, empezando por el punto en que decidí priorizar la mejora en la finalización de las tareas. De los 13 proyectos que empecé, sólo uno se convirtió en una zanahoria colgante perpetua que abandoné. Nueve proyectos terminaron después de una exitosa fase de exploración en la que decidí no seguir trabajando. Tres grandes proyectos fueron completados. El más orgulloso de los tres fue completar finalmente el proyecto con la descripción «Juro que finalmente terminaré este proyecto» mencionada en el párrafo introductorio.

Mi proyecto más reciente tiene una semana en este momento. Puedo ver claramente los impactos de las técnicas que he descrito en este artículo. He superado las incógnitas al pasar tiempo investigando, he evitado que se me desvíe por problemas de colas a medida que surgen, y he comprometido la funcionalidad del tamaño de la mordida para que mi código esté siempre en estado de funcionamiento. Este será mi proyecto más ambicioso hasta ahora y tengo la confianza de que podré llevarlo a cabo hasta el final manteniéndome en el camino correcto de explorar, hacer y terminar.

1] Manifiesto Ágil en inglés

2] Software orientado a objetos en crecimiento guiado por pruebas

Categorías: artesaníaTags: mejora continua, ágil