Herramientas que solucionan y ocultan problemas

Cuando era pequeño me sabía de memoria un montón de números de teléfono: el de casa de mis amigos, el de mis abuelos, el de algunos de mis tíos… Hoy en día, a duras penas recuerdo el mío.

La causante de todo esto es, claro está, la agenda del móvil, que me libera de tareas tan mundanas como recordar números de teléfono. A cambio, si me quedase sin batería y tuviera que llamar a alguien, tendría serios problemas para localizarlo.

En innegable que la agenda del móvil es una herramienta muy útil y que su contrapartida, es decir, no saber de memoria ningún teléfono de nadie, es fácilmente solventable, basta con memorizar un par de números para emergencias, pero eso no quita que confiar ciegamente en un herramienta también tenga sus consecuencias negativas.

En las últimas semanas he estado trabajando casi todo el tiempo en proyectos con Javascript y ReactJS usando simplemente un editor de texto y unas cuantas herramientas de líneas de comandos, lo que supone un cambio bastante grande con respecto a desarrollar en C# usando Visual Studio y Resharper.

Esto me ha hecho replantearme algunas cosas de la forma en que suelo programar y reflexionar sobre las implicaciones de usar herramientas avanzadas.

Solucionando un problema, ocultando otro. Solucionando un problema, ocultando otro.

A simple vista, uno diría que si tienes una herramienta más potente, que te permite hacer más cosas en menor tiempo y ser “más productivo”, la calidad del código debería ser mayor. A fin de cuentas, el usuario (o sea, yo) es el mismo, por lo que su capacidad para escribir buen (o mal) código es la misma, y cuantas más ayudas tenga mejor código escribirá, ¿no?

Lo cierto es que, en mi caso, no tengo tan claro que esto sea así.

Tener herramientas más avanzadas, como un compilador que chequea tipos o un IDE capaz de refactorizar y navegar automáticamente entre multitud de ficheros te ayuda a gestionar mejor la complejidad siempre creciente de un proyecto, pero también te oculta justo eso: que la complejidad está creciendo, y quizá demasiado.

A fin de cuentas, no necesitas prestar tanta atención al número de ficheros que creas o cómo organizarlos, navegar entre ellos es cuestión de pulsar una combinación de teclas y saltar de uno a otro.

O para qué pensar detenidamente el nombre de un método. Puedo poner el que quiera y, más adelante, renombrarlo en segundos. Siempre y cuando me acuerde de hacerlo y no quede con un nombre poco indicativo para siempre. Además, aunque sea un nombre poco memorable, tengo un completo intellisense que me ayuda a encontrarlo cuando lo necesito.

¿Y la gestión de dependencias? ¿Qué más me da si una clase se utiliza en 30 sitios distintos? Total, el using me lo añade automáticamente el Resharper y la dependencia la puedo acabar inyectando a través del contenedor de inversión de control.

Si quiero modificar código existente tampoco tengo problema, aunque eso introduzca fallos en mucho otros sitios. Lo modifico y el análisis en tiempo real de Resharper me irá guiando por todos los sitios en los que tengo que realizar correcciones. Correcciones que además muchas veces puedo automatizar y realizar sin prestar mucha atención.

¿Librerías externas? Todas las que quiera. Si necesito usar cualquier funcionalidad, usando un gestor de paquetes puedo añadir una librería que la implemente en un momento.

No es que la herramienta me obligue a hacer las cosas mal, pero me permite no prestar atención a esos pequeños detalles y vivir con la ¿falsa? sensación de que en realidad no son problemas, pero ciertamente los ejemplos que ponía puede ocultar problemas reales en una aplicación.

Tener un proyecto con miles de ficheros puede indicar que su tamaño es demasiado grande y que tal vez sería mejor partirlo en proyectos más pequeños, que pueda evolucionar y versionar por separado.

Escribir código de manera descuidada confiando en que luego refactorizarlo es fácil implica que si luego no me acuerdo de refactorizarlo, acabaré teniendo un montón de código escrito de manera descuidada.

Mantener una base de código en la que existen muchas dependencias interconectadas y clases que se utilizan en cincuenta sitios sólo porque es fácil depender de ellas acaba siendo un problema porque el acoplamiento entre unas partes y otras del sistema crece y es más difícil realizar modificaciones, ya que los cambios se propagan de unos puntos a otros.

Realizar cambios de forma masiva en el código, aunque tengas una herramienta que te guíe para solucionar los errores que estás generando, no suele ser una buena idea porque implica que están modificando demasiados sitios a la vez y el riesgo de introducir errores en mayor.

Introducir una librería con 5000 líneas de código sólo para utilizar un par de funciones que se pueden escribir en 5 minutos con 15 líneas de código añade una complejidad innecesaria a la hora de comprender las dependencias del proyecto e incrementa el API global con un montón de funciones que no necesitamos.

Sin embargo, cuando programo en Javascript usando un editor de texto, pierdo muchas de estas ayudas. Por ejemplo, para referenciar un fichero desde otro, es necesario hacer un require (o algo equivalente) a mano, lo que me hace ser muy consciente de cuantas dependencias tiene cada fichero porque me supone un esfuerzo extra añadirlas y mantenerlas.

Utilizar cientos de ficheros, aunque tengas ayudas para navegar entre ellos, se vuelve mucho más incómodo porque las opciones para saltar a la definición de un objeto o un método no son tan potentes como las del Visual Studio, y eso hace que te plantees si realmente necesitas tener un fichero para cada función o es preferible mantener ficheros un poco más grandes pero más cohesionados.

Puesto que renombrar es más complicado y recordar los nombres sin intellisense cuesta más, pongo más cuidado en intentar elegir un buen nombre desde el principio, y como cambiar la signatura de una función no es una tarea trivial (no tengo compilador ni Resharper), me cuido mucho de tener un método que se use en 1000 sitios diferentes por si tengo que modificarlo.

Eso hace que intente acotar más el uso de cada función para poder hacer cambios de forma más controladay y con menos riesgo de introducir errores.

Todo esto, que no nos engañemos, son limitaciones impuestas por el entorno, acaba redundando en que el código está más cuidado, resulta más compacto, más cohesivo y menos acoplado. Porque si no lo haces así, es imposible mantenerlo.

Cuando trabajo con este tipo de herramientas mi forma de trabajar cambia.

Mientras que con un IDE tiendo a escribir código rápidamente de la primera forma que se me ocurre porque sé que luego será fácil modificarlo aprovechando la potencia de las herramientas, si pierdo esa posibilidad, escribo código más despacio, pensando más lo que escribo pero dando menos vueltas para llegar al resultado final. Hammok driven development, que diría Rich Hickey.

En realidad, no creo que (al menos en mi caso) ninguna de las dos tácticas dé lugar a un código inherentemente mejor, y con ambas puedo llegar a conseguir escribir código muy bueno o código muy malo. Simplemente se trata de dos formas diferentes de trabajar impuestas por el tipo de herramientas que tengo disponibles y no deja de ser interesante plantearse esas diferencias y tratar de ver si se puede conjugar lo mejor de dos mundos.

No se trata de una adoptar una postura neoludista y renunciar a todo avance tecnológico, sino de ser consciente de que a veces las herramientas avanzadas nos puede hacer demasiado vagos y prestarle poca atención a la herramienta más poderosa que tenemos: nuestra capacidad de pensar y razonar.

Lo ideal sería tener toda la potencia disponible para cuando sea necesaria, pero no por ello dejar de pensar cuidadosamente en lo que estamos haciendo. Para eso hacen falta dos cosas: por una parte, ser consciente de cuando dejamos de pensar y nos dejamos guiar por la herramienta, y por otra tener una disciplina que no siempre es sencilla de mantener.

Y en eso estamos. Utilizar herramientas menos potentes me ha permitido ser consciente de algunos «vicios» que había adquirido por disponer de funcionalidades avanzadas y ahora, incluso cuando vuelvo a Visual Studio y Resharper, trato de ser más consciente del código que escribo y hacerlo mejor, independientemente de que las herramientas hagan tolerable trabajar con código de peor calidad.

2 comentarios en “Herramientas que solucionan y ocultan problemas

  1. miguelvelarde dijo:

    Lo mismo le digo a mi hija sobre el uso de la calculadora. Hoy en dia los niños ya no saben ni las operaciones basicas. El uso de las herramientas a veces nos hace olvidar o no aprender como se hacen las cosas.

Comentarios cerrados.