No hace mucho he leído en un libro sobre AngularJS la siguiente sendencia, aplastante e ilustrativa:

"Software development is hard. As developers, we need to juggle customer requirements and pressure of deadlines, work effectively with other team members, and all this while being proficient with multitude of software development tools and programing languages. As the complexity of software rises so is the number of bugs. We are all human and we will make mistakes, tons of them. Lower-level, programming errors are only one type of defect that we need to constantly fight. Installation, configuration and integration issues will also plague any non-trivial project."

(Mastering Web Application Development with AngularJS)

No lo habría podido expresar mejor: durante el desarrollo de cualquier proyecto, una de las tareas a las que nos dedicamos es a desarrollar nuevo código de producción, pero esta es una tarea más; al mismo tiempo se realizan muchas otras tareas relacionadas con el proyecto pero igualmente importantes. No obstante, en ocasiones se trivializa la importancia de esas otras tareas pensando que poco tienen que ver con el proyecto y que en realidad lastran el escribir nuevo código; porque lo divertido, lo que más nos gusta a los desarrolladores de software es "escribir código", ¿no es así?

Eso podría pensar una mente ingenua recién llegada a un sector en el que mirar hacia atrás varios años es ver la prehistoria por una renovación continua de nuevas tecnologías, flujos de trabajo y, por qué no, incluso nuevos tipos de proyecto.

Todas esas otras tareas alrededor del código son las que hacen que éste se escriba con calidad y que se trabaje de manera eficiente y productiva. Si esto no lo hemos asumido, entonces estamos aún varios pasos atrás de trabajar realmente como profesionales. La calidad de un proyecto no sólo se mide porque el cliente obtenga un producto software de utilidad, también por cómo el mismo proyecto software pueda evolucionar, ser mantenido y evolucionado, y, además, en mi opinión una cuestión que no siempre es evidente, que los desarrolladores puedan trabajar en él de manera eficiente, productiva y con satisfacción.

De ninguna manera podemos pasar a codificar como siguiente paso una vez que tenemos claro los requisitos. Cuando comenzamos un nuevo proyecto, antes de teclear la primera línea de código, tenemos que definir claramente, entre otras cosas:

  • Las tecnologías más apropiadas a usar y la fricción entre ellas. Como apuntaba en un post anterior, en el desarrollo de aplicaciones web modernas, por poner un ejemplo, nos podemos encontrar con una explosión de librerías y frameworks que continuamente te hacen dudar si estás eligiendo la mejor opción.
  • Definir el flujo de trabajo (workflow) de los desarrolladores y ciclo de vida.
  • Detectar todo aquello que se pueda automatizar (compilaciones automáticas, pruebas de validación finales, etc). Esto es un elemento de apalancamiento impresionante y no siempre se tiene en cuenta: cualquier esfuerzo dedicado al principio en este punto, nos ahorrará ese esfuerzo multiplicado a lo largo de la vida del proyecto. Como mantra, yo siempre me digo que "todo aquello que hacemos manualmente en el proyecto varias veces al día se debe intentar automatizar". Esto hace posible que una vez que estemos trabajando en el proyecto nos dediquemos básicamente a implementar historias de usuario, la funcionalidad que se nos ha pedido.
  • Definir también cuál va a ser la estructura del proyecto: en qué carpeta va a ir el código, dónde y cómo se van a generar las pruebas, dónde se van a incluir los assets del proyecto, etc. Esta definición evitará que los miembros del equipo vayan incluyedo todos estos artefactos donde mejor les parezcan y sin coherencia.
  • Desde un primer momento, definir el despliegue del proyecto en producción para así anticipar desde la primera entrega problemas que de otro modo surgirían al final.

Todo esto, digo, se tiene que definir y poner en práctica antes de teclear la primera línea de código. La tentación de pasar directamente a desarrollar para tener algo que mostrar cuanto antes es en engaño que nos autoinfligimos: de tener todo lo anterior bien claro y definido, dependerá que ahorremos muchísimo esfuerzo en el futuro y, por tanto, redundará en la calidad del producto que generemos.

De aquí se pueden crear algunas reglas sencillas que debemos seguir siempre, como aquella que repito tal que no se realiza ninguna actividad si esta no ha sido previamente planificada, por ejemplo:

  • No se implementa nada nuevo si no ha sido incluido en la fase actual de trabajo con los tiempos de desarrollo estimados.
  • No doy por finalizado nada si no he creado las pruebas necesarias para demostrar (hoy, mañana, la semana que viene, etc.) que funciona.
  • No genero ningún nuevo artefacto software si antes no se ha establecido dónde y cómo tiene que ser generado.
  • ...

Estas reglas, sencillas en esencia, suponen la base por la que un equipo de desarrollo trabajará de manera productiva y ordenada.

Con la irrupción de los smartphones y tablets de los últimos años y el paso acelerado de parte de la economía tangible a la economía digital, el desarrollo web se ha visto tremendamente fragmentado, sectorizado y disperso en un conjunto cada vez mayor de tecnologías heterogéneas. No es raro que cualquiera que se acerque por primera vez a la programación web sienta cierto vértigo al decidir qué herramientas usar, qué tecnologías emplear. Aquí hay que hacer un auto de fe que en ocasiones te lleva a estudiar a fondo los frameworks más de moda con el riesgo que esto supone.

Muy lejos queda cuando alguien era capaz de definirse como maquetador web o web master (sólo pensar en estos conceptos trasnochados me chirrían los oídos), aunque no es raro que aún se incluyan esos términos en algunos currículums... El panorama ha cambiado radicalmente y ha evolucionado tanto que la industria ahora bendice todo lo que suene a estándar o tecnología no propietaria.

Hoy es tal la cantidad de opciones disponibles para comenzar un nuevo proyecto web que es tremendamente difícil acertar en las más adecuadas dada las características del proyecto. Algunas preguntas recurrentes suelen ser:

  • ¿Me baso en un CMS flexible como Drupal?
  • ¿Lo hago desde cero (...)?
  • ¿Diseño mobile first o desktop first?
  • ¿Evolucionará el proyecto mucho, poco o nada en el futuro?

... y esto si no caemos en el error que querer usar porque sí las tecnologías que más conocemos y que más cómodas nos resultan (por eso de evitar salir de nuestra zona de confort).

Ya el concepto de programador web tiene poco contenido, al menos a mí me dice más bien poco: ¿especialista en front-end, en back-end, en despliegue de infraestructura, en diseño, en usabilidad, SEO, etc.? Me temo que no todo el mundo puede ser excelente en todas esas áreas, de ahí la fragmentación y la realidad ineluctable para la que un proyecto más o menos extenso tenga que contar con perfiles diferenciados.

Desde hace mucho hemos pasado del concepto de página web a aplicación web para la que su desarrollo requiere de habilidades y roles bien distintos:

  • Diseño y usabilidad (user experience o UX). El éxito de cualquier web, sobre todo si se basa en la atracción de tráfico para generación de contenidos o ventas va a depender directamente de un buen diseño y una magnífica usabilidad. Además, hacer un diseño responsive puede ser todo un reto y un trabajo adicional importante a considerar.
  • Front-end, es decir, todo aquello que muestra al usuario final el contenido de la web y le permite interactuar con ella.
  • Back-end: todo lo que se cuece por detrás y que da soporte al front-end: APIs basadas en web services o servicios REST, acceso a base de datos, etc.
  • Si existe una base de datos, su buen diseño y mantenimiento es una tarea relevante.

Necesario pero no suficiente... una aplicación web tiene que ser desplegada en algún entorno e infraestructura IT: ¿servidores web Apache, Nginx, LightTpd, IIS, en la nube con Amazon EC2 o Azure de Microsoft? Esos entornos, lógicamente, tienen que estar bien configurados y correctamente mantenidos y todos son un mundo en sí mismos.

Una vez desplegada la web y en funcionamiento de cara a los usuarios, el trabajo no queda ahí: hay que medir la web tanto en el éxito de su funcionamiento como en el uso que hacen de ella los propios usuarios; es ahí donde interviene la analítica web. Si además al sitio no llega nadie (que vendría a ser algo así como pintar un cuadro maravilloso pero que nadie ve) habría que implantar tácticas SEO y SEM. Es más, esas tácticas se implantan no al final de desarrollo sino también durante el mismo: forman parte del mismo desarrollo del proyecto.

Lo que quiero destacar aquí es el carácter heterogéneo y poliédrico del desarrollo, evolución y mantenimiento de una aplicacion web que queda muy lejos del concepto simplista de quien se autodenomina programador web; así las cosas, mejor definirte en tu propio currículum como experto en ciertas áreas tales como:

  • Experto en front-end basado en Foundation, Bootstrap, etc.
  • Desarrollador de back-ends basados en node.js, APIs REST, ASP.NET Web API, etc.
  • Diseñador especializado en comercio digital, usabilidad y RWD (responsive web design)
  • Administrador de sistemas web basados en tecnologías LAMP.
  • Conocimientos de diseño web y UX.

Anótate esto y ahora mismo ve a cambiar tu currículum indicando un perfil más explícito como los anteriores.

Y, para colmo, ¿qué hay de todos los aspectos sobre seguridad?. La seguridad afecta transversalmente a varios de los roles que hemos identificado anteriormente, de modo que a la lista anterior añadiríamos:

  • Experto / auditor en seguridad web.

De este modo cada vez que me llega un currículum con una línea en donde pone desarrollador web, pues..., la verdad, no sé exactamente qué pensar.

No es sólo cuestión de en qué rol te identificas más o menos, en cual tienes más o menos experiencia, es que, además, para cada uno de ellos las herramientas, tecnologías, frameworks, etc. que existen son extraordinariamente amplias, por lo que podemos caer en el riesgo de especializanos en algún framework que hoy día puede ser muy popular pero del que nadie hable dentro de un tiempo.

Si trabajas en el desarrollo web y tus habilidades, herramientas y tecnologías que conoces son las mismas que hace tres años, aún no te han dicho que vives en la prehistoria y toca reciclarse, además profundamente.

La miríada de conocimientos, librerías y frameworks disponibles para un desarrollador de front-ends, por poner un ejemplo, son tan extensas que te hace dudar realmente de lo que sabes o dejas de saber: Foundation de Zurb, Bootstrap, Semantic UI, Gumby Framework, Javascript (esto es para despistados), CSS3, preprocesadores como Less y Sass, Blueprint CSS y un larguísimo etcétera aparte de pequeñas librerías imprescindibles como jQuery, Modernizr, HTML5Shiv, Respond...

Que haya tantas opciones, algunas excluyentes y otras complementarias en el mismo proyecto es en mi opinión extraordinariamente bueno, ya que así podemos afinar mucho sobre qué usar según las características del proyecto a realizar; sin embargo, tantas opciones pueden tener un lado muy perverso:

  • ¿Tendrán continuidad las librerías / frameworks que elijamos?
  • Si evolucionan, que sin duda lo harán, habrá que tener en cuenta el coste de adaptar y migrar nuestras soluciones ya en producción a las nuevas releases, si es que no queremos que llegue el momento de tener que mantener proyecto con librerías obsoletas dentro de algunos años.
  • Sin duda, si elegimos ciertas librerías nuevas para nosotros, su curva de aprendizaje supondrán un coste a añadir en el desarrollo del proyecto.

Este es un aspecto del desarrollo de software que comento prolijamente en El Libro Negro del Programador: la línea sutil que separa la elección de un buen conjunto de tecnologías y su evolución futura sin comprometer los proyectos cuando estén el produccion.

El desarrollo web es hoy día más poliédrico que nunca, más diverso que hace tan solo dos años y, precisamente por ello, con más opciones de desarrollo profesional que antes. Si te consideras un programador web activo, muy activo, pues enhorabuena, ¡no te vas a aburrir!

¿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.

Páginas

¿Por qué leer El Libro Negro del Programador?

Adquirir desde:
Amazon (kindle eBook / papel)
CreateSpace (papel)
PayHip (epub / mobi / pdf)

El libro negro del programador.com
Segunda Edición - 2017

Archivo

Trabajo en...

Mis novelas...