¿Somos los mejores profesionales que podríamos llegar a ser?

¿Aportamos valor realmente a la compañía para la que trabajamos o a los clientes que nos pagan los honorarios? ¿o nos limitamos a hacer lo que nos dicen y nada más y no sabemos tomar la iniciativa en ningún asunto?

Se usa a menudo la expresión aportar valor pero en la mayoría de las ocasiones sólo queda como un simple titular de promoción interna en los departamentos de recursos humanos. Queda muy bien, pero realmente no se cambia absolutamente nada para que exista una cultura corporativa que promueva el valor, el talento y la proactividad. Veo demasiada gente hablando de proactividad pero actuando muy poco proactivamente: decimos una cosa pero después hacemos otra totalmente distinta. A mí esto me suena al principo de la locura.

No sabremos aportar valor en nuestro entorno si no invertimos en nosotros mismos. Es, de hecho, la mejor inversión que podemos hacer.

Desde hace unos años participo en cierta medida en asuntos comerciales además de mi dedicación casi completa a dirigir un equipo de desarrollo, involucrándome, cómo no, en todo tipo de tareas técnicas, decisiones de diseño y arquitectura, toma de feedback de clientes, etc.

En este tiempo me ha llamado mucho la atención cómo bastantes clientes pontenciales de los productos que comercializamos se interesan por conocer el motor de base de datos que usa nuestro software. Los hay quienes le dan todas las bendiciones a SQL Server, otros que no cambiarían Oracle por SQL Server y unos pocos que nos han preguntado si el sistema podría funcionar con Cassandra (...). Nada que objetar, salvo su percepción completamente errónea de que el producto va a ser rápido y eficiente o lento y poco escalable según la base de datos que use, nada más.

Esta suposición, entendible para cierto perfil no técnico, la he visto también en otro tipo de perfiles muy técnicos y entendidos en software, para mi asombro.

La escalabilidad de un producto software no depende necesariamente de la base de datos que use, ni mucho menos: ésta es un elemento más de la larga lista de características que se le deben exigir a un producto software escalable.

No sólo he tenido que sufrir este tipo de polémicas en el eterno debate que si SQL Server  / Oracle, sino que además, todo lo que huela ahora mismo a volúmenes grandes de información rápidamente se asocia a la necesidad de una solución big data con Hadoop o MongoDB, confundiendo necesidades de almacenamiento con necesidades de análisis y procesamiento de la información.

Pero, ¿qué entendemos por escalabilidad? Esto va a depender el tipo de productos del que estemos hablando: para un portal web es sin duda el soportar un número alto de usuarios simultáneos, para una aplicación de análisis de datos, el poder captar y procesar cierto volumen de información; para un sistema de gestión de dispositivos físicos, como contadores digitales, por citar algo más ligado a mi actividad, no es lo mismo gestionar mil que cien mil dispostivos en un mismo sistema, con cinco o con cien operadores simultáneos.

Si un producto software usa una base de datos, de cualquier tipo que sea esta (relacional, no-sql, documental, etc), ésta por sí misma no va determinar el rendimiento del producto.

Esto que parece una perogrullada lo he tenido que explicar más de una vez a personas que se dedican a desarrollar software...

¿Qué determina un buen uso de una base de datos?

Este es un tema extraordinariamente amplio, pero para dar una idea de que el buen uso de una base de datos no es del todo trivial, podemos decir que no puede haber deficiencias en el diseño, sin redundancias innecesarias, las consultas a la base de datos deben ser sencillas y eficientes, se debe minimizar el número de consultas, cada consulta debe traerse la información estrictamente necesaria, las transacciones se deben dejar para las operaciones imprescindibles, debe hacerse un estudio concienzudo de los índices necesarios según la naturaleza de las consultas a realizar, según los casos habría que optar por las estructuras eficientes que ofreza el mismo gestor de bases de datos (particionado horizontal y vertical, por ejemplo), no mezclar una base de datos pensada para almacenamiento histórico con la base de datos de trabajo, dejar, si se puede según la idiosincrasia del producto, los procesamientos masivos de información para momentos que no interfieran en las ventanas de operación de los usurios clientes, y un largo etcétera .

Si este tipo de cosas no están bien resueltas, de nada nos servirá el mejor motor de base de datos.

En mi experiencia he visto claramente cómo la forma de almacenar la información determina lo sencillo o complejo que puede ser gestionarla por el software cliente de alto nivel. En ocasiones no falla cómo accedemos a la información, sino cómo esta información se encuentra almacenada en el repositorio de datos.

La forma en que necesitamos la información y cómo ésta se encuentra almacenada van de la mano.

Podemos incidir y hacer un buen trabajo a ese nivel mejorando el modo con el que nuestra aplicación accede a la base de datos, pero me temo que no queda la cosa resuelta del todo.

¿Qué ocurre con la arquitectura del propio sistema?

En cierto sentido, esta arquitectura va emergiendo a medida que intentamos que admita más y más dispositivos, usuarios o las entidades que representen la escalabilidad para nuestro producto.

Sin embargo, cuando hablamos de sistemas con grandes volumenes de procesamiento de información, tareas, procesos, etc. la arquitectura del sistema software es fundamental. Aquí ya hablamos de desarrollar software a otro nivel, con otro tipo de estrategias de diseño y desacoplamiento entre subsistemas para que cada uno haga su tarea de manera muy eficiente.

No hay estrategias generales que resuelvan cada caso concreto, pero sí buenas prácticas arquitecturales.

El poder distribuir estos subsistemas entre servidores distintos es todo un reto también de diseño para que todas las instancias puedan realizar su trabajo concurrentemente balanceando el trabajo, tanto si nos apoyamos en terceros sistemas para este propósito como si no.

Una aplicación que funciona bien para diez usuarios concurrentes no tiene nada que ver en diseño, arquitectura y diseño de repositorios de datos para la misma aplicación que tenga que dar servicio a 10k usuarios, por poner un ejemplo. La arquitectura no tendrá nada que ver, el diseño general y los microdiseños serán muy diferentes de un sistema a otro y el diseño y uso de la base de datos también serán extraordinariamente distintos.

La cuestión es que pocas veces comenzamos a desarrollar un nuevo producto sabiendo a ciencia cierta lo escalable que tiene que llegar a ser y en qué momento de su tiempo de vida deberá admitir más usuarios, dispositivos, etc. Hace falta mucha experiencia para prever esta arquitectura y los diseños adecuados. ¿Y entonces?

No existen soluciones mágicas para casi nada, pero lo que sí puedo asegurar es que si se comienza haciendo diseños limpios, con mucho esfuerzo en generar código desacoplado y de calidad, con una batería de pruebas suficientemente amplia, exhaustiva y mantenible, si nos esforzamos en cada fase del desarrollo del producto en identificar qué partes presentan cuellos de botella mediante análisis de rendimiento, etc. podremos tener un sistema para el que poder escalarlo no se convierta en algo dramático.

En ciertos sistemas complejos y más o menos grandes, todo, absolutamente todo cuenta: una iteración simple entre los elementos de una lista parece algo inocuo, pero cuando se ejecuta en un servidor cientos de miles de veces en un día, puede presentar un problema de rendimiento cuyo efecto se acumula desastrosamente a otros, presentando finalmente un problema global de rendimiento. Los detalles sí que importan.

Escribir código que funcione es nuestro trabajo, también es escribirlo de manera que funcione y que sea lo más limpio y simple posible, pero también que esa eficiente, lo que ya no es tan trivial en algunas ocasiones.

De hecho, existen libros dedicados a este asunto, como uno al que recurro habitualmente: Pro .NET Performance, por poner un ejemplo.

Otro recurso que uso confrecuencia (ligado a las tecnologías que más uso), es Improving :NET Application Performance And Scalability.

Por último, nada peor que encontrar problemas de rendimiento cuando el producto ya está en producción, si eso ocurre es que no se ha hecho un trabajo del todo bueno probando el sistema con anterioridad. No sólo hay que realizar tests unitarios, de validación e integración, también de rendimiento.

Así las cosas, cada vez que un cliente potencial con el que seguramente tenga media hora sólo para hablar, me pregunta qué base de datos usa el sistema, comprenderéis lo complicado que a veces resulta defender una respuesta cuando el cliente está más predispuesto hacia otro tipo de gestor de bases de datos que la que usamos.

Quizá nos han educado para buscar un empleo del que vivir, trabajar en algo con lo que ganarnos la vida y pagar las facturas a final de mes. Quizá, digo, no pusieron durante nuestra educación el énfasis necesario para que siempre busquemos trabajar en algo que no sólo nos guste, sino que nos apasione. Otra cosa distinta es que eso mismo lo busquemos como empleado o como empleador, aunque lo que aquí quiero recalcar es que la excelencia, la calidad, siempre surge cuando amamos lo que hacemos con una intensidad superior al resto de nuestras obligaciones.

No existe ningún trabajo en el que todas las tareas que tienes que realizar sean siempre gratas; para conseguir un objetivo final, un proyecto con resultados, hay que hacer muchas cosas diferentes, unas nos pueden gustar más, otras menos, pero si cuando terminamos el proyecto, dando paso a una nueva fase en él o comenzando otro completamente nuevo, no sentimos cierta satisfacción, orgullo personal o una sencilla alegría por haber terminado algo con calidad y lo mejor posible dadas las circunstancias, entonces es que no estamos dedicando nuestra vida laboral a lo que realmente nos apasiona.

En software esto tiene un impacto enorme, aunque no siempre nos damos cuenta de las consecuencias desastrosas que esto tiene para la ejecución con éxito de un proyecto.

De acuerdo, hay quienes son capaces de dedicar ocho o más horas a una actividad que ni les va ni les viene, lo cual no deja de ser una virtud, necesaria además en aquellos países donde la crisis financiera todavía tiene un impacto grande. No obstante, quienes nos planteamos nuestra carrera laboral como algo ascendente, con pasos positivos y progresivos hacia el éxito, lo que sea que cada uno entienda por éxito, no podríamos trabajar en algo por lo que realmente no sentimos pasión.

Nunca vas a ser bueno, un profesional altamente cualificado, si has elegido hacer algo que no te llena, que no te gusta. Es así de sencillo pero así de contundente.

Del mismo modo, en una profesión donde la excelencia tiene una relación tan directa en la vida de los productos software que construimos, esta característica de los desarrolladores es más relevante que en cualquier otra profesión.

Me gusta mi profesión, a veces tan poliédrica, me gusta realizar productos que le resulta a un usuario final de enorme utilidad. Hay ocasiones en las que un sencillo pero elegante refactoring que hago y que mejora de algún modo la calidad del código que escribo, me hace sentir muy bien.

Igualmente me siento bien cuando me resulta fácil detectar cualquier problema en la instalación de un cliente donde tenemos desplegados algunos de nuestros productos (se ha hecho el suficiente esfuerzo para que el software se pueda depurar), cuando nos plantean una nueva necesidad y vemos que perfectamente se puede encajar en las capacidades de integración del producto, cuando un cliente te felicita porque le resulta fácil utilizar la interfaz de usuario sin recurrir a la guía de usuario (interfaces amigables) o cuando te felicita también porque lo que antes tardaba en hacer varias horas, ahora lo puede realizar a golpe de clic ahorrando costes a su compañía (valor para el cliente final), y un largo etcétera.

Para conseguir eso, hacen falta muchísimas horas de trabajo, disciplina, perseverancia en la creación de pruebas unitarias y de integración, refactorización continua de código y de diseños en cada nueva funcionalidad, clase, librería, etc. implementada y todo eso, desde luego, no se podría hacer si no te has vuelto adicto a ese momento mágico en que etiquetas una nueva versión de tu producto o creas un nuevo branch sabiendo que la versión que cierras en ese momento está bien conseguida, tanto en funcionalidad como en calidad interna de código. Si a esto lo llamamos excelencia, entonces no puedes llegar a ella si pasas ocho horas o más al día trabajando esperando que te ingresen una nómina a final de mes.

Uno de estos momentos, que yo llamo de epifanía, fue cuando colgué mi primera web allá por el 2008 (bueno, no es que ahora esté realmente orgulloso de ese trabajo, pero esa era mi primera incursión en entornos web después de años dedicado a aplicaciones y entornos de backend muy escalables y optimizados).

Una persona que no encaja en lo que hace y en lo que pasa muchas horas de su vida, necesariamente no se va a esforzar por realizar el mejor trabajo posible: la pregunta que los desarrolladores de software profesionales se deben hacer cuando terminan una tarea, es ¿puedo mejorar esto en algo?, ¿puedo abstraer de aquí algo para mejorar el diseño de la solución?, ¿podría simplificarlo aún más?.

Un desarrollador puede terminar su trabajo y ya está, un desarrollador bueno se plantea algunas o todas esas preguntas de vez en cuando o puntualmente, pero un desarrollador excelente se hace esas preguntas continuamente.

Como responsable de grupo de trabajo, una de mis funciones es crear un equipo con personas que se sienten a gusto haciendo lo que hacen, que les guste realmente la mayor parte de las tareas de desarrollo que desempeñan, pero, sobre todo, que se sienten felices cuando se termina algo con una calidad magnífica.

No podemos innovar en áreas de trabajo que no nos gustan del mismo modo que no podemos ser lo más productivos posibles en aquellos trabajos que odiamos.

La primera vez que leí sobre este aspecto del desarrollo de software fue en The Passionate Programmer, de Chad Fowler, uno de los libros que descubrí hace años y que me convencieron de que programar era mucho más que escribir líneas de código.

Sólo podemos programar bien si realmente nos gusta este trabajo y esta profesión tan exigentes.

Esto es exactamente de lo que habla Ken Robinson en el TED en la charla antológica y su libro El Elemento, de cómo la pasión por lo que uno hace lo cambia todo:

https://www.ted.com/talks/ken_robinson_says_schools_kill_creativity

En El Libro Negro del Programador se insiste mucho (como en cualquier otro libro que nos enseñe a ser mejores profesionales) que la refactorización de código no es sólo una herramienta que debemos usar sino que ésta es un hábito que emplear en el día a día y que distingue a los mejores desarrolladores de software.

No obstante, el concepto de refactorizar se suele entender exclusivamente como un trabajo de modificar líneas de código y mejorarlo sin afectar a su comportamiento externo; conseguimos, efectivamente, limpiar en cierta medida el código para que sea de mejor calidad, más legible y mantenible.

Siempre insisto en que esto no es algo que se hace o no, sino que forma parte del hecho de programar una solución, es algo consustancial a la misma.

Cuando terminamos de implementar una nueva funcionalidad, siempre nos debemos preguntar ¿podemos mejorar lo que hemos implementado en algún aspecto?, ¿se puede simplificar?, ¿se puede mejorar en relación al proyecto general como parte que se pueda reutilizar?, etc. Lo sorprendente es que cuando te creas el hábito de plantearte este tipo de cosas apenas termina haciendo falta hacerlo al final de implementar algo, ya que tienes el hábito de hacer las cosas limpias desde un principio de modo que al final, es esfuerzo o tiempo que empleas como puro trabajo de refactorizar es mínimo.

No obstante, se suele entender por refactorizar el trabajo de mejora del código, pero ¿qué ocurre con la misma estructura de un proyecto que va creciendo y creciendo con el tiempo? No hablo de diseño, sino de cómo están organizadas las carpetas, subproyectos, etc.

Cuando un proyecto crece en tamaño (en forma de librerías dispersas, multitud de sub-proyectos, demasiadas dependencias externas, incluso una estructura de los proyectos de pruebas compleja) se debe y tiene que refactorizar igualmente.

Recientemente hemos cerrado una nueva revisión de uno de los proyectos en los que trabajamos actualmente (la Plataforma de Telegestión y MDM IRIS para dispositivos de telemedida PRIME). Pues bien, he planteado unos días de trabajo para mejorar la estructura interna del mismo para evitar que sea cada vez más compleja (de gestionar y de trabajar sobre ella).

En concreto, algunas de las cosas que vamos a evaluar son:

  • Unificación de algunas librerías dispersas que podrían vivir en un único proyecto.
  • Integración de algunos subproyectos pequeños que podrían vivir coherentemente en otros.
  • Mejora de la distribución y estructura de las puebas de integración.
  • Plantear las bases para que el gestor de tareas, ahora muy ligado a la idiosincrasia de la solución, viva como un framework independiente del proyecto (y reutilizable por otros proyectos que pongamos en marcha).
  • etc.

¿Qué pretendo conseguir con esto?

Cuando un proyecto crece en complejidad, cuando hablamos de cientos de miles de líneas de código, aunque esté todo realizado con extremada limpieza y con una arquitectura general y microdiseños muy cuidados, la misma distribución de los artefactos del proyecto puede ser un problema que impida llegar a los sitios con sencillez y comodidad. La espaguetización del proyecto no sólo se puede producir en su código sino también en la estructura misma de sus módulos.

De este modo, al mejorar y simplificar cómo están distribuidas y organizadas las cosas, ganamos agilidad y comodidad a la hora de trabajar en una nueva revisión. Lo que no es fácil de ver es que esta agilidad y comodidad se traduce después en ahorro de muchas horas de trabajo. Coseguimos la máxima calidad en algo cuando tenemos un entorno cómodo de usar y de trabajar. La facilidad de mantenimiento también tiene mucho que ver con esto.

Detrás de cada acto de refactorización, del tipo que sea, se esconde un ahorro de tiempo futuro al dedicar menos esfuerzo y tiempo en evolucionar una aplicación bien hecha, o lo que es lo mismo, el tiempo invertido en refactorizar se traduce en una mejor productividad (= menos recursos económicos necesarios para hacer algo).

Me sorprende a menudo cómo los desarrolladores de software nos complicamos la vida por no dar un paso atrás e identificar aquello que nos impide centrarnos en escribir código de producción y testearlo. Los problemas casi siempre surgen de no montar en entorno adecuado de pruebas que permita testear la nueva funcionalidad que incorporamos con comodidad. El extremo más radical de esto consiste cuando la única posibilidad de probar algo es ¡en el entorno de producción del cliente!. Me temo que sólo mecionarlo se me pone la piel de gallina, aunque lamentablemente lo he vivido y lo he visto en varias ocasiones.

Cuando comienzo un nuevo proyecto, aunque sea sencillamente probar una tecnología que desconozco y con la que comienzo a jugar, lo primero que hago es montar un entorno en el que trabajar con absoluta comodidad: si no lo hacemos así, a los problemas habituales de resolver errores y avanzar en aquello que no conocemos bien le añadiremos los inconvenientes de trabajar con ese entorno incómodo (o lo que es lo mismo, perderemos más tiempo en problemas con el entorno que en crear software útil).

Por poner un ejemplo, últimamente estoy haciendo algunas pruebas de concepto implementando algunos módulos en node.js que acceden a un servidor MongoDB. Lo primero que he hecho ha sido instanciar una máquina virtual con un Ubuntu Server en el que arrancar MongoDB; una vez que aprendo a limpiar completamente todas sus colecciones y realizar las tareas de administración básicas y suficientes para las pruebas que quiero implementar, todo lo demás lo puedo realizar mucho más rápidamente y cómodamente y, sobre todo, en pocos pasos.

Esto parece una trivialidad, pero si no lo hacemos así y estas operaciones elementales no las hiciera con sencillez, me resultaría muy complicado avanzar en las pruebas de node.js que estoy realizando: terminaría hastiado y acabaría abandonando más pronto que tarde.

El pricipio que me encanta aplicar en esto es aquel que indica que para las tareas repetitivas, sólo deberíamos trabajar una vez.

Efectivamente, sólo dedico algo de tiempo al comienzo para crearme un entorno de trabajo lo suficientemente cómodo como para poder centrarme en las pruebas o lo más importante del trabajo que me propongo realizar.

No hace mucho terminé de leer un libro que me ha encantado; se trata de El Efecto Compuesto de Darren Hardy (se puede encargar en español aquí), sobre cómo los pequeños hábitos y las pequeñas acciones, mantenidas en el tiempo y con constancia, representan realmente una gran diferencia.

Del mismo modo, ¿como sería nuestro trabajo si cada vez que quisiera ejecutar la prueba X necesitara pasar cinco minutos limpiando una base de datos, levantar ciertos servicios, etc.?, ¿cuánto tiempo perderíamos al usar un editor que no dominamos del todo?, ¿cuánto tiempo perdido si tuviéramos que probar algo leyendo el resultado en un documento txt?.Para ser productivos escribiendo el código de producción en el que trabajamos tenemos que crearnos entornos sencillos y eficientes, lo que requerirá seguramente dedicar algo de tiempo la primera vez que se genera ese entorno, aunque esa pequeña inversión de trabajo y tiempo la rentabilizaremos con creces posteriormente.

De nuevo, vemos cómo un buen y profesional desarrollador de software, competente en su ámbito, con suficiente experiencia, no llegaría al 10 si no se rodea de hábitos y condiciones que permiten que su trabajo se haga con comodidad y eficiencia.

Una nueva fase

Un artículo de Rafa G. Blanes

Después de año y medio, ya está disponible el libro completamente revisado y reeditado en todos los sites de Amazon, tanto en papel como en formato Kindle.

Me han preguntado recientemente que qué se puede esperar de El Libro Negro del Programador: muy resumidamente siempre digo que ojalá hace ocho o diez años alguien me hubiera hecho notar o advertido sobre ciertos aspectos del desarrollo de software, no necesariamente técnicos, porque se da la circunstancia de que cuando un proyecto falla, casi siempre lo hace por las mismas razones: mal talante técnico, desastre organizativo y de planificación, equipos no coherentes, falta de un mínimo de metodología y un largo etcétera, pero casi siempre son las mismas circunstancias.

En ocasiones veo que ciertos desarrolladores de software más que programar bien, tratan de jugar chapuceramente con lo que hacen. Debemos y podemos ser profesionales buscando la calidad de nuestro trabajo al tiempo que lo hacemos lo más lúdico posible. En este sentido, y parafraseando un capítulo del libro MBA personal de Josh Kaufman, para progresar en nuestras carreras debemos tratarnos y gestionarnos como si fuésemos empresas: nuestro mejor activo somos nosotros mismos, siempre buscando ofrecer y hacer un trabajo de calidad.

¿Y a partir de ahora qué?

En el libro se han incluido varios capítulos inéditos; uno de ellos es el Test del Desarrollador de Software Altamente Productivo, en donde se identifica mediante un juego sencillo de preguntas, qué hacemos bien y no tan bien para trabajar productivamente (es decir, no perder el tiempo, que es nuestro único activo de valor y conseguir más y mejores resultados). En los próximos meses iré desarrollando todas esas preguntas, al menos las más relevantes, en el blog de El Libro Negro del Programador, entre otras cosas.

Espero de verdad que os sea útil este trabajo.

Los principios de trabajo "lean" me entusiasmaron desde el primer momento en que tuve conocimiento de ellos. El desarrollo ágil viene de la aplicación en cierta medida de los principios de desarrollo lean y guarda muchas similitudes con estos principios. Como todo, si algo es simple, fácil de entender y sencillo de poner en práctica y de sentido común tiene el éxito garantizado. No obstante, me sorprende cómo muchos de estos principios son totalmente desconocidos para muchos desarrolladores de software y emprendedores de cualquier naturaleza.

El Libro Negro del Programador ha sido escrito siguiendo algunos de los principos lean y su finalización (en el momento de escribir esto está en fase de edición) ha sido posible por y gracias a esta metodología.

Muy pero que muy básicamente, la concepción lean en el desarrollo de un proyecto nuevo y emprendedor viene a indicar que no podemos esperar al final del mismo para comprobar si va a tener éxito o no. ¿Cómo puedo averiguar si una idea genial que he tenido puede convertirse en un éxito comercial? Uno de los errores de muchos emprendedores es volcar todo el esfuerzo, tiempo y dinero en terminar algo completamente antes de lanzarla y después esperar (y rezar) para comprobar si tiene buena acogida o todo lo contrario. En ocasiones cuando se llega al final ha pasado tanto tiempo que la genial idea ya ha sido superada por otras en el mercado, o bien se pule y refina el proyecto tanto que se sufre de parálisis por análisis.

Una de las historias fascinantes que cuenta Eric Ries en El Método Lean Startup es la del dueño de Groupon, actualmente una multinacional con presencia y servicio en multitud de países para el intercambio y promoción de cupones de descuento. Desde luego no invirtió en crear toda la infraesctutura actual de Groupon para ponerse en marcha, sino que comenzó muy humildemente probando el concepto con sus familiares y amigos y, de ahí, según la respuesta obtenida, fue mejorando continuamente y dándole forma como proyecto empresarial. Convirtió una idea sencilla, práctica y barata de probar, en una compañía global.

Del mismo modo, desde El Libro Negro del Programador he ido compartiendo los avances de los capítulos para obtener feedback y comprobar el grado de interés que pudiera despertar un proyecto así. ¿No ocurre lo mismo que en software cuando le enseñamos a un cliente cómo se van implementado las historias de usuario para afinar en requisitos y su idea de lo que quiere y necesita?

Afortunadamente, desde los primeros capítulos, El Libro Negro del Programador despertó suficiente interés como para perserverar en su avance, en forma de correos de ánimo, mensajes sobre erratas, sugerencia de nuevos capítulos, puntualizaciones, diversos puntos de vista, ayuda para revisar los documentos gramatical y ortográficamente (gracias Luis)  y, para mí lo más gratificante, preguntas del tipo "¿cuándo y cómo podré adquirir el libro?".

El método lean no sólo te ayuda a comprobar el interés en algún tipo de idea o proyecto, sino que te permite mejorarlo y afirnarlo mediante una táctica de pivotar sobre la idea o perseverar en ella.

Estamos aprendiendo a hacer las cosas de otro modo, a emprender proyectos con otras tácticas; también la redacción de un libro se puede enfocar así.

Me he encontrado en ocasiones algunos desarrolladores de software que, al menos aparentemente, se obstinan en hacer las cosas exageradamente complicadas. Tanto es así que parece que lo hacen como seña de identidad: cuanto más abstruso más demuestro lo bueno que soy. Digo yo que lo mismo iban por ahí lo tiros.

No obstante, la pregunta que hay que hacerse cuando escribimos una nueva pieza de código es, "¿lo entenderemos nosotros mismos dentro de un tiempo?", si la respuesta es afirmativa, la siguiente pregunta sería "¿lo entenderán los demás, aquellos que hereden para lo bueno o para lo malo este trabajo?".

Yo siempre digo que si el primer objetivo de un buen software es resolver algún problema y que le sea de utilidad a alguien, lo segundo es que debemos programar para que los demás puedan asumir fácilmente aquello que hacemos. Nada más ingenuo que pensar que cuanto más rebuscado hagamos el trabajo mayor la estima técnica que nos puedan tener.

Un cosa clara me ha demostrado la experiencia, algo además irrefutable: las mejores soluciones con las que más me he sorprendido, han sido claramente las más sencillas. Todos podemos deliberadamente hacer algo complejo, pero pocos, muy pocos, podemos dar con el medio o la solución más sencilla.

Este debería ser uno de los prinpios con los que trabajar en el día a día: intentar buscar siempre la solución más sencilla a cualquier problema, tanto de programación, de diseño, etc.

No sólo este principio mejorará nuestros productos, nuestro día a día en el futuro cuando tengamos que volver a modificar una aplicación, sino que con el tiempo te das cuenta de que el hábito constante de buscar siempre simplificar las cosas, precisamente te reprograma la cabeza para que de manera natural te surjan soluciones sencillas.

Recomiendo encarecidamente la lectura (y relectura) del libro Code Simplicity, el libro de Max Kanat-Alexander, ingeniero software en Google en donde reflexiona sobre estos conceptos que tanto pueden hacer por mejorar la calidad del trabajo que realizamos. Su blog también contiene entradas muy interesantes.

¡Vamos llegamos al final del libro!

Después de más de un año dándole forma a El Libro Negro del Programador, ya es hora de darlo por cerrado y publicarlo oficialmente.

Como siempre he indicado a lo largo de los capítulos, su versión publicada en la web son adelantos: la versión final del libro tendrá los capítulos más desarrollados, con más ejemplos y además se incluirá una serie de capítulos inéditos, entre ellos el de conclusiones y uno que me gusta especialmente: el test del desarrollador de software altamente productivo.

Es sorprendente la cantidad de cosas que te planteas y re-planteas cuando escribes sobre los temas que te gustan y apasionan: una cosa es creer que sabes algo y otra muy distinta ponerlo por escrito para contárselo a otros, sobre todo de una forma que hasta tu abuela lo tendría que entender.

No sé si he tenido mucho o poco éxito, pero la motivación principal de El Libro Negro del Programador es la de allanar el camino a quienes llegan a nuestra profesión y a quienes llevan más tiempo pero que creen que han alcanzado todo lo que había que saber...

Si es verdad que aprendemos de los errores, en el libro tenéis los que desde mi punto de vista cometemos con más frecuencia los desarrolladores de software y que nos impiden trabajar con la excelencia como único propósito; porque lo que sí tengo más que claro es que la economía que viene no es la de la titulitis, sino la del talentismo, o como diría el gran Raimon Samsó, la clase emergente de los expertos.

En los próximos días se publicará un último capítulo y en unas semanas podréis disfrutar del libro editado con profesionalidad desde distintos portales en Internet.

Gracias y hasta pronto.

Software testing

Reconozco que comencé a tomarme muy en serio el ser más estricto con el desarrollo y refactorings de las pruebas desde hace relativamente pocos años. Efectivamente, me llevó su tiempo darme cuenta de la enorme rentabilidad metodológica al pasar de una aplicación de consola para depurar (...) que tener formalizadas correctamente una completa y contundente batería de pruebas. Tanto es así, que hoy día sólo veo a través de las pruebas, quiero decir, cuando desarrollo nuevo código de producción, pocas veces entro en él en modo depuración si las pruebas correspondientes indican que todo va bien.

(Update: no en vano he publicado en 2019 un nuevo trabajo sobre todas aquellas prácticas ágiles que permiten escribir código mejor diseñado y de mejor calidad y que permite así escribir mejores tests: El Libro Práctico del Programador Ágil)

No obstante, y sin caer en la simpleza de reconocer lo fácil que es detectar en qué otros fallan, veo a menudo (muchas más veces de las que me gustaría) que el hecho de tener implantantado una arquitectura y metodología que permite y exige el crear pruebas, éstas se desarrollan como para salir del paso, en lo que se suele en llamar el happy path y que yo llamo particularmente "pruebas felices".

¿Qué es una prueba feliz?. Cuando escribimos una nueva clase o añadimos una nueva funcionalidad a código ya existente, tenemos la tendencia natural de escribir pruebas que consciente o inconscientemente sabemos que van a dar pocos problemas. Probamos entonces el mejor caso y que resuelve bien nuestro código: la prueba feliz viene a decirnos que nuestro código hace bien aquello para lo que lo hemos desarrollado. No obstante, si nos limitamos a escribir exclusivamente pruebas felices, estamos ignorando gran parte del objetivo de tener una solución respaldada por tests. Buscamos sólo pruebas felices porque en realidad percibimos el escribir pruebas como un mal que hay que asumir en lugar de un pilar fundamental y esencial en el desarrollo de un software de calidad y profesional.

El objetivo de escribir pruebas no es sólo el de tener un mecanismo por el que poder comprobar automáticamente que algo funciona ahora y seguirá funcionando en el futuro. Escribimos tests no sólo para la situación ideal (el camino feliz) sino que debemos desarrollarlos para comprobar todas aquellas situaciones incómodas en las que una funcionalidad particular se podría ver comprometida. Se nos olvida en ocasiones que los tests persiguen detectar errores, si nos quedamos con los casos más sencillos, seguramente estaremos ocultando bugs que tarde o temprano nos explotarán en las manos.

¿Cuándo es el momento más oportuno para detectar errores y problemas?, ¿cuando estamos precisamente desarrollando una nueva funcionalidad o cuando el software está ya en producción con uno o varios clientes usándolo?. La respuesta es más que obvia.

Recientemente he desarrollado un servicio de Windows para instanciar ciertos servicios web que emulan el comportamiento de un tipo de dispositivo. Se simula uno de estos dipositivos instanciando sus servicios web correspondientes en un puerto específico. Desarrollé como es lógico ciertas pruebas para garantizar que los web services se instancian bien para el puerto 8000, ¿y ya está?. Absolutamente no, ¿qué pasaría si al desplegar ese software en una máquina en producción ese puerto está ya siendo usado?. En este caso, las pruebas tienen que garantizar que somos correctamente notificados cuando se da esa circunstancia, que un error de este tipo no provoca un crash completo del servicio de Windows, etc. Si me hubiera quedado en la prueba feliz, seguramente habría terminado antes, pero con toda seguridad en el futuro habría tenido que dedicar muchísimo más tiempo a solucionar ese tipo de errores en producción y con un cliente insatisfecho...

Esto no es más que un ejemplo pero es que a veces no nos damos cuenta de la cantidad de esfuerzo y tiempo que nos podemos ahorrar detectando errores en producción sencillamente creando una batería correcta de tests en la fase de desarrollo. Pocas cosas hay que tranquilicen más en software que saber que tu producto está tan suficientemente probado que muy difícilmente se van a encontrar problemas en el despliegue del mismo.

Una ley del software viene a ser que cuanto más y mejor pruebes un software, mayor lo vas a rentabilizar, en el sentido de dedicar menos tiempo a depurar errores, el tener menos clientes reportando problemas, etc.

Tampoco es cuestión de crear el mayor número de pruebas porque sí sino de crear éstas con la calidad suficiente y cubriendo todos los posibles casos.

Este es un asunto que, me temo, solemos subestimar y es que no es trivial crear y saber desarrollar pruebas con la suficiente calidad; el problema es que en nuestra profesión muy a menudo debemos tener un carácter polifacético (lo que viene siendo tener que hacer de todo un poco); este no es un tema sencillo sino que el tester es un claro perfil de persona cualificada con ciertas aptitudes en su profesión, como bien indica este magnífico libro de Software Testing.

Páginas

Mis libros en todas las tiendas:

Amazon
Google Play
Apple
Kobo
Barnes and Noble
Scribd
Smashwords
Payhip
Gumroad

Rafael Gómez Blanes Rafael Gómez Blanes
¿Hablamos?

 

Trabajo en...

Archivo

Mis novelas...