Desde hoy está disponible El Libro Negro del Programador en cualquier tipo de dispositivo Android. Me complace mucho poder difundir este trabajo en una nueva plataforma y poder llegar así a más usuarios, más aún en una con tanta difusión como tienen todas las apps de Google Play.

Google Play Logo

Aprovecho para indicar que en pocas semanas estará también disponible El Libro Práctico del Programador Ágil, trabajo en el que podrás aprender todo lo relacionado con la creación de software de calidad, desde las técnicas básicas de código limpio, refactoring, principios SOLID hasta una introducción al testing y la gestión de la configuración. Este último trabajo es muy ambicioso y muy práctico, con gran cantidad de ejemplos en C# y Javascript. Además, se discuten técnicas de productividad para desarrolladores de software y por qué, en esencia, cualquier software se corrompe si no se siguen buenas prácticas de desarrollo y diseño.

Actualmente estoy muy involucrado dirigiendo un proyecto en el que debemos desarrollar un framework corporativo para una compañía de fabricación de componentes aeronáuticos. El objetivo a medio plazo del proyecto consiste en que la compañía tenga los pilares fundamentales sobre los que construir toda la funcionalidad de tipo ERP y procesos de negocio, algo bastante ambicioso.

¿Qué tienen en común este proyecto (o las necesidades de esta compañía) en relación al sistema software que necesitan poner en marcha y otros similares? Me lo he encontrado en otras ocasiones: negocio que avanza rápido y cuyas necesidades también progresan de la noche a la mañana.

Por detallarlo mejor:

  • Distintos perfiles de usuario deben acceder al sistema para utilizarlo según su rol (operarios de fabricación, directivos, ventas, recursos humanos, etc.)
  • Todo debe estar integrado en un mismo proyecto que dé servicio a todos. Nada peor que necesitar un conjunto de aplicaciones dispersas e independientes entre ellas para darle de comer al negocio, de ese modo, imposible (o muy costoso) realizar cualquier tipo de analítica, la dirección no puede tener visibilidad real de los detalles del día a día, etc.
  • Las necesidades cambian continuamente, debiendo incorporar más funcionalidad frecuentemente. Esto forma parte de la esencia del sistema.
  • El negocio dependerá completamente de este sistema, lo que implica una gran responsabilidad (hablamos de millones de euros de facturación, glups...)

¿Cómo afrontar un desarrollo de este tipo?

Ya pasé por la experiencia de un proyecto con características similares en el que se planteó (en contra de mi criterio) una arquitectura demasiado "ad hoc" y monolítica para cubrir lo anterior, de modo que ante las necesidades anteriores, una mejor aproximación consiste en crear un sistema con una arquitectura basada en componentes (de ahí lo de framework corporativo) y cuyas tecnologías se usen lo más desacopladas posible (para un proyecto cuyo servicio debe durar muchísimos años, nada peor que vincularlo totalmente a un mismo repositorio de datos o tecnología web). En este caso, usamos .NET framework pero lo dejamos todo listo para utilizar .NET Core tan pronto como éste comience a estar más maduro (algo que sin duda ocurrirá a medida que se vaya implantando).

Esta arquitectura no es ninguna novedad: directa o indirectamente, muchas soluciones de mercado la siguen, desde CMS como Drupal (y su ampliación de funcionalidad mediante módulos) hasta la extensibilidad de funcionalidad de Alfresco. Es decir: existe un framework a modo de core que ofrece una funcionalidad base que se puede extender mediante plugins, extensiones, componentes o módulos (el nombre es equivalente, lo que importa es el concepto, aunque en el contexto de este artículo los denominaré a todos como "componente").

¿Qué hace ese framework base? Se encarga de lo siguiente:

  • La gestión de usuarios (login, registro de actividad, altas, bajas, etc.).
  • Todo lo relacionado con la seguridad (roles, permisos, autentificación, tokens para las APIs, etc.).
  • Aisla del tipo de repositorio de datos utilizado (los componentes ni siquiera deberían saber que lo que hay detrás es un Sql Server, Sql Azure, MySql, Oracle, Redis o cualquier otro medio de persistencia de datos).
  • Nivel de presentación: el framework se encarga del proceso básico de construcción de la interfaz de usuario (lo habitual es estar basado en alguna tecnología web).
  • El framework ofrece una API mediante la cual se puede extender su funcionalidad mediante componentes: esta es una parte esencial y la razón de ser del framework.
  • Debe permite activar, desactivar, instalar o desinstalar componentes en caliente.
  • Permite añadir nuevos componentes al sistema sin necesidad de pararlo temporalmente, garantizando un funcionamiento 24/365 (salvo en actualizaciones del mismo framework, claro). Esto facilita un enfoque DevOps para la compañía.
  • Asiste a los componentes cuando cambian de una versión a otra, para que la migración sea lo más fácil posible, así como la implementación de esa migración.
  • Es escalable: varias instancias del framework pueden convivir en diferentes servidores como redundancia por seguridad y para soportar cargas altas de trabajo.

Fácil de decir pero no tan sencillo de implementar.

Por otra parte, y gracias a todo lo anterior, un componente puede:

  • Añadir nueva funcionalidad al sistema (nuevas entidades de datos exportables, tareas recurrentes, eventos, nuevas vistas, nuevos informes, etc.)
  • Un componente se debe poder implementar fácilmente, ya que gran parte del trabajo pesado lo realiza el framework. Debe existir una guía de desarrollo de componentes para que cualquier desarrollador pueda extender la funcionalidad.
  • Un componente puede tener asociado una interfaz de usuario (mediante una vista o bloque que se renderizará de algún modo, esto es trabajo del framework)
  • Puede definir sus necesidades de almancenamiento de información (pero sin ensuciarse con los detalles de creación de entidades, tablas, índices, etc. según el tipo de tecnología a usar; esto es trabajo del framework).
  • Puede comunicarse con otros componentes.

De este modo, un sistema así está compuesto del mismo framework, un conjunto de componentes del mismo framework (core components) y otro conjunto de componentes de usuario (user components). En el caso en el que estamos trabajando, se llegará a tener con toda probabilidad más de cincuenta para conseguir toda la funcionalidad requerida.

Ni que decir tiene que en un proyecto de esta naturaleza, el framework tiene que ser una pieza software robusta y con una cobertura de tests muy alta, con un diseño impecable, limpio y mantenible.

Al igual que cualquier otra actividad, programar "bien" no es solo cuestión de conocimientos técnicos, sino de saber "trabajar correctamente", en un entorno en el que padecemos cada vez más una epidemia de dispositivos y aplicaciones que compiten por nuestra atención las veinticuatro horas del día y que terminan, a menos que lo evites, por consumir gran parte de tu tiempo de forma improductiva y, lo peor, impidiéndote estar concentrado en una tarea más de unos pocos minutos.

Estamos ante una enfermedad del siglo XXI: la incapacidad cada vez mayor de mantener la atención y la concentración.

Leí hace unas semanas este artículo que recomiendo "Focus and Deep Work — Your Secret Weapons to Becoming a 10X Developer", en el que habla sobre las técnicas que se utilizan para programar no solo mejor, sino más rápido, de modo que a partir de ese artículo, voy a hacer mis propias reflexiones, porque lo que sí puedo confirmar rotundamente es que los equipos y proyectos que mejor funcionan, no son los que trabajan más horas, sino los que trabajan mejor.

Hecho nº1: cualquier tarea de naturaleza creativa, necesita de una capacidad de concentración elevada.

Y ya sabemos que programar bien, es más que un arte.

Hace un tiempo leí el libro de Cal Newport "Deep Work: Rules for Focused Success in a Distracted World" (está en inglés pero hay un resumen en castellano), y en él se afirma que la "atención" va a ser un recurso cada vez más escaso, de modo que los mejores profesionales (y los más demandados) serán aquellos que gestionen mejor su atención y su capacidad de concentración.

No puedo estar más de acuerdo, ya que yo mismo, si echo la vista atrás y veo cómo se trabajaba hace quince años o al inicio de mi carrera profesional, veo que hay muchas diferencias. No hace tanto, las posibilidades de distracción e interrupción eran mucho menores; éramos, digamos, personas menos dispersas en tanto que lo que teníamos a nuestra disposición para aprovechar los ratos muertos del metro o el bus, eran un periódico, un libro o un reproductor de mp3. Ahora llevamos un smartphone que nos da todo eso y mucho más en el mismo dispositivo, incluida una infinidad de opciones, distracciones, interrupciones y formas de perder el tiempo. 

Hecho nº2: prueba a poner el móvil en modo avión una hora y a programar sin conexión a Internet tan solo con el IDE abierto. ¿Te sientes nervioso o como si te faltara algo? Chungo.

Vivimos estresados innecesariamente con interrupciones que casi nunca nos aportan algo, confundiendo el ocio con saber trabajar bien: es cierto que podemos controlar las interrupciones hasta cierto punto, pero para ser realista, pocas personas lo hacen, porque esa notificación de tus colegas o pareja, esa noticia de última hora o el último mensaje de un primo tuyo en Facebook, te saca de la tarea aburrida que estás haciendo por un instante, de modo parece que así se pasa el día mucho más ameno, pero no te das cuenta de que apenas has podido concentrarte en nada y, por tanto, lo que podías haber terminado en una hora, tardas varias, con un resultado acumulativo desastroso a lo largo del mes.

Hecho nº3: pagas un precio muy alto por esa dispersión continua, aunque no sea evidente.

Como desarrolladores de software, este efecto es devastador, puesto que como sabemos, debemos tomar decisiones de diseño continuamente (microdiseños), debemos estar atentos a cualquier posibilidad de refactorización, etc., y nuestro trabajo es en gran medida acumulativo: construimos software sobre lo que hicimos ayer, antes de ayer, etc.

Hecho nº4: escribirás mejor software cuanto más seas capaz de permanecer concentrado. No hay más.

Hay quien puede permanecer una hora en esa inmersión mental como mucho, otros dos o tres. Perder la concentración nos cuesta una media de veinte minutos para volver al mismo estado en que teníamos antes, y si sabemos que solo podemos hacer un buen trabajo (y en menos tiempo), estando concentrados, entonces esto es una necesidad obligada.

Hay muchas razones que nos impiden trabajar concentrados (a lo mejor te suenan):

  • Interrupciones telefónicas.
  • Un compañero de al lado muy pesado.
  • Avisos de notificaciones continuas desde el móvil o la barra de tareas de tu sistema operativo.
  • Reuniones improvisadas.
  • Mantener el cliente de correo abierto continuamente y estar atento a nuevos emails en la bandeja de entrada.
  • Tener en la cabeza ese ronroneo continuo de algo incómodo que tienes que hacer durante el día...

El entorno puede que tampoco ayude:

  • Trabajas en una oficina con ruido constante y con muchas distracciones visuales.
  • Tu lugar de trabajo es hostil y, por alguna razón, no te encuentras cómodo en él.
  • Tienes el escritorio hecho unos zorros, sin darte cuenta de que ese desorden afecta también a tu concentración.

Pero, ¿cómo trabajar centrado en una tarea durante un tiempo razonable para terminarla bien y en poco tiempo?

Aquí van algunos consejos que aplico desde hace mucho tiempo:

  • Suelo tener cada día identificadas las tareas que debo realizar. Parece una trivialidad, pero saber qué diez asuntos tienes que atender en las próximas horas, te produce la sensación de trabajar en un entorno más controlado y tranquilo, y esto favorece la capacidad de concentración.
  • Te quitas de encima en primer lugar las tareas que menos te gustan. Nada peor que trabajar sabiendo que aún te queda pendiente esa llamada incómoda o ese informe aburridísimo que tienes que terminar.
  • Si tienes la opción del teletrabajo, encuentra un lugar cómodo y que te inspire donde sepas que no te van a interrumpir.
  • Cierra cualquier cosa que te pueda molestar mientras estás realizando la tarea (gestor de correo, notificaciones, pones el móvil en silencio, etc.).
  • Si es necesario, indica con alguna señal a tus compañeros que en la próxima hora necesitas que no te interrumpan.
  • Autosecuéstrate: indica a tus reponsables o compañeros que hoy, de diez a dos, quieres dejar de existir para el mundo para centrarte al máximo en algunas tareas difíciles y exigentes que tienes por delante. Esto funciona de maravillas, aunque parezca de excéntricos.
  • Evita responder a llamadas en el periodo en que estás inmerso en la tarea.
  • Reduce al máximo la necesidad de trabajar colgado al teléfono continuamente: si acostumbras a que te llamen para todo, serán los demás quienes gestionen tu tiempo, y no tú, cuando, de verdad, en muy pocas ocasiones hay algo verdaderamente urgente que atender. Por extraño que parezca, a los clientes también se les puede instruir para que su forma de contacto eficiente contigo sea el correo.
  • Si tu jefe no es receptivo en relación a esto, cómprale un ejemplar de Deep Work o explícale que lo que quieres es ser más productivo y aumentar la calidad de lo que haces.
  • Implanta la técnica del Pomodoro para la realización de tus tareas.
  • Deja las tareas de diseño y de desarrollo de código nuevo para las mañanas, y por la tarde las tareas de creación de tests, documentación, mejoras, etc. Después de dormir, el cerebro tiene más energía para las tareas creativas, aunque para esto, lo mejor es que te conozcas a ti mismo y sepas cuándo funcionas mejor según qué tipo de trabajo.
  • Dedica unos minutos por la tarde noche para repasar mentalmente, aunque sea por encima, lo que tienes que hacer al día siguiente. Mágicamente, en el día siguiente tienes que dedicar mucho menos esfuerzo para organizar la jornada.
  • Huye como de la peste de los vampiros de tiempo.
  • Anota tu productividad en forma de tareas realizadas, verás cómo haciendo pequeños cambios como los descritos anteriormente, vas a obtener mejores resultados.

Y si quieres ser todavía más frikie, dedica unos minutos al día a meditar cada cierto tiempo...

 

Hace muchos años creí que siendo un buen técnico me aseguraría un sueldo con el que pagar las facturas. Y así fue, no lo puedo negar: en mi anterior compañía para la que trabajaba tuve muchas oportunidades de participar en proyectos muy diferentes, ganando con el tiempo experiencia no solo técnica sino también de contacto con el cliente final. Fui aprendiendo que las dinámicas de trabajo y de grupo, el ambiente, la mala gestión del tiempo, etc. afectaban a veces de forma dramática a un buen desarrollo de software. Y también pasé muchísimo tiempo desarrollando software, es decir, acumulé mucha experiencia y muy varidada, por lo que me siento muy afortunado.

Y fueron pasando los años..., y el trabajo seguía igual de exigente con sus momentos de estrés muy duros y asfixiantes, y a medida que pasaba el tiempo en el que sacaba los proyectos con éxito junto con mis compañeros, mi consideración en la empresa era creo que buena, o sea, que estaba bien considerado y me gané de algún modo la confianza de mis colegas y jefes, al menos de casi todos.

Cuando me quise dar cuenta, puesto que me etiquetaron en la categoría de "tipo que saca las cosas adelante", fui encontrando barreras ya no solo para cambiar de proyecto o departamento, también para ascender, porque, lamentablemente, esa era la única forma de pasar al siguiente nivel económico, al menos en la cultura empresarial predominante en mi país. De algún modo, me encasillaron como imprescindible en algunas áreas y de ahí no me querían sacar. Es decir, la gente no me quería quitar de donde estaba porque era suficientemente bueno en ello y, paradójicamente, esto me bloqueaba para desarrollar más mi carrera profesional.

No estoy hablando de relucientes compañías de Sillicon Valley financiadas con capital riesgo tirando la casa por la ventana en donde un desarrollador (según he leído) puede llegar a ganar al año cifras de seis ceros. Estoy hablando de un momento previo a la crisis del 2008 en el que un ingeniero informático con titulación universitaria dedicado al desarrollo de software tampoco era pagado con una cifra extraordinaria; se puede vivir de eso, claro, pero lo lógico es que con el tiempo quieras avanzar más económicamente, al menos algo, digo yo.

Esta es una realidad incómoda: es difícil prosperar mucho económicamente dedicándote exclusivamente al desarrollo de software, menos todavía dentro de una compañía. Por muy bueno que seas, lo vas a tener difícil si tu objetivo es ganar mucha más pasta, me temo. No digo que sea imposible, pero sí afirmo que es improbable.

Y, paradójicamente, la economía digital nos asegura trabajo, pero no así un magnífico salario; al menos en mi país, y a pesar de la crisis, es relativamente fácil poder vivir trabajando como desarrollador, técnico IT, analista, etc. Pero..., a ver, a medida que vas cumpliendo años, la escala laboral y salarial van divergiendo, o sea, que cada año que pasa aumenta la sensación de que estás bloqueado, cuando no atascado, en el tema económico. Y esto es lo que hay. No tengo más que ver a conocidos de más de cuarenta años de edad que siguen realizando tareas de desarrollo principalmente, igual que hace diez años y están, prácticamente, en el mismo sitio. Técnicos excelentes, pero una cuenta bancaria estancada. Según tus inquietudes, esto ni te lo planteas, pero me consta que a todo el mundo le gustaría ganar más.

Y no digo que sea malo, ni mucho menos, pero si tu objetivo es prosperar mucho económicamente, entonces ser un profesional muy pero que muy bueno no te asegura nada, con todas las excepciones que puedan haber.

Y, sin embargo, nunca ha sido más fácil contar con más de una fuente de ingresos, tener tus propios productos que vendes globalmente y desarrollar una idea con muy bajo presupuesto, tal y como recoge este libro que gustó mucho: 100€ startup.

Nunca fue más fácil obtener ingresos que en la economía digital, y quienes estamos más cerca a ella por nuestra profesión, tenemos, por tanto, una barrera de entrada mucho más estrecha y accesible.

¿Alternativas?

Aquí van algunas ideas si quieres examinar algunos caminos interesantes:

  • Montar tus propios micronegocios más o menos relacionados con las actividades que conoces bien y que además te gustan.
  • Pensar en no trabajar por horas, sino a comisión o por resultados. ¿Es mejor cobrar 100€ más al mes o poseer el 20% de "algo" que se puede vender miles de veces?
  • Desarrollar una idea propia de negocio y encontrar el entorno adecuado para desarrollarla.
  • Escribir libros y cobrar royalties sobre temas técnicos que conoces bien.
  • Crear video cursos y ofrecerlos en portales como Teachable.
  • Ofrecer servicios a través de portales como Fiverr para acaparar encargos frecuentes.
  • Publicar en GitHub un buen proyecto por el que puedas cobrar por una licencia comercial o por horas de soporte, como OrmLite o Picly.io.
  • Seguir los pasos de libros como Start Small, Stay Small

Y, nos guste o no, cualquier actividad de los puntos anteriores implica pasar parte de tu tiempo ajeno a tareas exclusivamente ténicas; para ello tendrás que trabajar directamente con clientes, mejorar tu comunicación, aprenderás que el marketing y la promoción son temas imprescindibles, del mismo modo que desarrollar un negocio, aunque sea pequeño, también te va a llevar a aprender a gestionar equipos y hasta tener cierta cultura financiera, laboral y contable.

Jo.

A menudo me he cruzado mensajes con personas que me han pedido más o menos consejos sobre sus primeros hitos como desarrolladores de software y, también, tengo la oportunidad con frecuencia de tratar con quienes acaban de terminar su ciclo académico (tanto de la Universidad como de una modalidad que existe en mi país a través de módulos formativos). 

¿Qué decirles a aquellas personas que comienzan en este sector y cuyo interés principal es programar?

Qué decir cuando cada uno cuenta con sus propias experiencias a lo largo de su vida profesional, y también cuando está claro que cada uno tiene sus propios objetivos; yo puedo decir que cuento con una experiencia dilatada en muchísimos proyectos de naturaleza completamente heterogénea, algunos de los cuales fracasaron y otros continúan funcionando en alguna parte del mundo. Según éstos, tu progresión profesional y formativa deberá ir cambiando en una u otra dirección: ¿te ves trabajando para una gran compañía el resto de tu vida? ¿o bien te resulta más atractivo cambiar cada pocos años o incluso crear tu propio negocio?

Lo primero que te voy a decir es que si llevas varios años realizando el mismo tipo de actividad... pues mal, muy chungo, vas por muy mal camino.

Por otra parte, hay que tener en cuenta que el mercado laboral local en el que cada uno vive tiene características diferentes y al final nos tenemos que adaptar un poco al tipo de compañías que tenemos más accesible, si es que te das cuenta pronto de que también puedes teletrabajar ofreciendo tus propios servicios como agente libre.

Aquí va una serie de consejos que espero que sean de utilidad, enfocados para un desarrollador de sofware neófito pero ambicioso y que comprende que:

  • Nuestro mercado es mundial, no local. ¿Te das cuenta? ¿Por qué ofrecer tus servicios a las compañías de tu propia ciudad cuando lo puedes hacer a todo el globlo?
  • El inglés es el idioma natural en todo lo relacionado con el software. Lo siento, es así, si no dominas el inglés, al menos el técnico, reduces tus posibilidades.
  • No hace falta vivir o trabajar en Silicon Valley para lanzar proyectos importantes.
  • Tan importante es la actitud como la aptitud, tendrás que cultivar y mejorar ambas.
  • El desarrollo de software, aunque tenga una base sólida desde hace muchas décadas, evoluciona a un ritmo frenético: o te actualizas casi continuamente, o en cinco años eres un dinosaurio tecnológico. Tenlo en cuenta; esto es: tienes que aprender continuamente, del mismo modo que tendrás que desechar gran parte de tus conocimientos técnicos que terminan siendo obsoletos. Nada peor que aferrarte a unos conocimientos cuyo valor en el mercado tiende a... cero.

Un programador que empieza y que quiere mejorar...:

  • Debe aceptar que solo va a ser un buen programador cuando haya trabajado varios años escribiendo código, muchísimo código. Me molesta mucho quienes dicen cosas como que "ya picaron código durante un par de años...". Los conceptos básicos de programar se pueden aprender en un curso de fin de semana... Pero lanzar un proyecto profesional requiere de mucho más tiempo y experiencia. Programar es un arte, difícil, y si no que se lo digan a Uncle Bob...
  • Un buen programador siempre acepta que puede haber una solución mejor que la suya (= humildad). Lamentablemente, en este sector te vas a encontrar con muchos egos subidos que creen que por escribir dos tonterías en un ordenador, están enviando un cohete a Marte... Acostúmbrate a tratar con personalidades con egos demasiado inflados. Mi consejo: aléjate de ellos, la mayoría están defendiendo su puesto de trabajo.
  • Un buen programador lee código de otros y le gusta husmear en GitHub o sitios similares para ver el trabajo de los demás.
  • Se documenta y lee continuamente acerca de nuevas tecnologías, tendencias, etc.
  • Antes de reinventar la rueda, investiga para comprobar si ya existe algo parecido a lo que tiene que realizar, es decir, integra librerías o servicios de terceros en su trabajo. Nuestra responsabilidad es crear valor, no rediseñar soluciones que otros ofrecen a bajo precio mucho mejor de lo que podríamos desarrollar por nuestra cuenta.
  • Debe dominar todo lo relacionado con el código limpio y técnicas de refactoring.
  • No concibe escribir código que no pueda ser respaldado por tests y no duerme bien si su software no está suficientemente testeado...
  • Como mucho puede llegar a dominar unas cuantas tecnologías (dos o tres, digo "dominar con carácter de experto"), pero sí sabe "algo" de muchas otras.
  • Se mantiene al día de lo que acontece en la industria del sofware (al menos de lo que ocurre en su sector): contenerización, cloud, software as a service, microservicios, etc.
  • Los mejores desarrolladores que he conocido siempre trabajan en proyectos propios y personales al margen de su actividad regular (quizá haya sido casualidad, pero no lo creo).
  • Tu mejor currículum es una web personal propia donde hablas del trabajo que realizas y enlazas algunos proyectos hechos por ti y publicados. Gestionar tu marca personal como si de una empresa se tratase.
  • Nada peor que trabajar en el mismo proyecto durante mucho tiempo. Esta actitud provoca que trates de defender una posición que crees exclusiva en la compañía, y puede que así sea, pero te está impidiendo progresar y mejorar como profesional en otras áreas. En El Libro Negro del Programador dedico un capítulo a esta dinámica.
  • Ningún profesional es monolítico y solo domina un área del desarrollo de software: hay que tener conocimientos variados aunque sea superficiales, de bases de datos relacionales y no relacionales, de algorítmica, de diseño web, de microservicios, de testing, de métricas y calidad del software, etc. No hay nadie que sea experto en todo, y si alguien se identifica así, está lejos de la realidad. Nuestro sector está cada vez más especializado en áreas completamente heterogéneas.
  • Un buen desarrollador sabe distinguir lo que es el diseño y lo que es la arquitectura.
  • Abraza el desarrollo ágil sí o sí.
  • Sabes que la mejor forma de mejorar en programación es, programando muchísimo...
  • Siempre se pregunta "¿cómo puedo mejorar y simplificar esto?".
  • Un buen programador sabe que hay que trabajar sí o sí con cierta metodología.
  • Utiliza herramientas para el seguimiento metodológico del proyecto en el que trabajo (Visual Studio Online, Asana, Trello, etc.)
  • Aunque tu dedicación fundamental sea programando, también tienes algún conocimiento de infraestructura, administración de sistemas, etc.

Un buen programador (o alguien que prospera programando, que no tiene por qué ser lo mismo), y al igual que ocurre con cualquier otra profesión, no cultiva solo su aspecto y saber técnicos (algún que otro hijo de p... que he conocido podía ser "bueno" en lo suyo pero insufrible como persona, perdiento, por tanto, oportunidades), sino que cultiva y mejora también su actitud:

  • Sabe trabajar en equipo y se integra bien cuando tiene que compartir su trabajo.
  • No se siente amenazado ante quienes tienen más experiencia: lo ven como una oportunidad de aprender más y no como una amenaza.
  • Sabe soportar los momentos de estrés y gestionarlos como algo más que forma parte de la dinámica profesional.
  • Es organizado en el trabajo y sabe distinguir las tareas importantes de las urgentes.
  • Tiene conocimientos de productividad en el trabajo.
  • Es amable con sus compañeros y cuida el modo en que se expresa con ellos.
  • Me di cuenta hace mucho que cuanto más sabiduría alcanzas, más humilde eres, lo contrario es el ego insoportable de quienes te debes alejar como de la peste, en serio.
  • Transmite a su jefe de forma clara lo que necesita para trabajar correctamente.
  • Se mantiene enfocado: evita las distracciones continuas e interrupciones mientras está en un ciclo de trabajo (de una a dos horas como mucho).
  • No lo quiere hacer todo él mismo, sino que sabe que en ocasiones tendrá que delegar.
  • No trabaja en lo que más le gusta en cada momento, sino en lo que hay que hacer.
  • Se compromete con su trabajo.

Así que ya vemos que una cosa es la actitud y otra bien distinta la aptitud, y que ambas son importantes para un buen profesional.

Por último, es indudable que hoy día los mercados de mayor crecimiento están el desarrollo de aplicaciones móviles, web y todo lo relacionado con los servicios cloud.

Y, por supuesto, un buen profesional no comete los errores que describo con precisión en El Libro Negro del Programador...

Hace un tiempo tuve una reunión de trabajo en la que me crucé con alguien que empleaba un tono demasiado altisonante para lo que mis oidos están acostumbrados, hablando con una suficiencia técnica un poco insoportable, para ser sincero. Cuando se dirigía a mí, parecía que me estuviese examinando. Después me comentaron su trayectoria profesional y me llevé una gran decepción, con todos los respetos. Dos años atrás, me encontraba ante un proyecto bonito, interesante y en crecimiento, liderado por personas competentes, sin duda, pero que en su carrera profesional solo habían conocido... ese único proyecto bonito e interesante. De vez en cuando recibo currículums de ingenieros técnicos en informática cuya experiencia laboral se basa en demasiados años en la misma compañía y en el mismo departamento, haciendo exactamente lo mismo.

Cada uno hace lo que puede para progresar en su carrera profesional, claro está. En definitiva, cada uno es libre de hacer con su tiempo y vida lo que le dé la gana. No es ni bueno ni malo estarse años en una misma actividad, lo que quiero puntualizar aquí es que puede ser muy peligroso y que en ocasiones hay quienes venden demasiado humo aparentando una imagen profesional basada tan solo en sus años de experiencia o quienes incluso alardean de llevar muchos años cuando en realidad han pasado ese tiempo realizando tan solo un conjunto muy limitado de cosas en concreto.

Pero lo que me molesta un poco, y lo siento, es que cualquiera alce como bandera de competencia técnica o de gestión únicamente los años que lleva currando: solo eso, mucho tiempo, como si solo éste fuese suficiente para darle más credibilidad a tu currículum.

En mi opinión, no solo son importantes los años que lleves trabajando en un sector u otro, sino además el contenido con el que has llenado tantas horas de trabajo para una empresa u otra. No tiene nada que ver haber trabajado en dos o tres proyectos similares que en veinte totalmente diferentes, el profesional que sale de lo segundo cuenta con una visión y experiencia mucho mayor y mejor, aunque haya dedicado la mitad de tiempo que quienes llevan en lo mismo el doble.

Lo que no se aprecia con claridad es que puedes llevar muchos años trabajando pero, en realidad, tan solo cuentas con un único año de experiencia, porque el resto del tiempo has estado repitiendo exactamente la misma actividad. En cierto modo, llevas despertándote en el mismo lugar cada mañana como Bill Murray y Andy MacDowell en la película de El Día de la Marmota

Es posible que en software, después de trabajar en muchos proyectos totalmente diferentes, se termine cultivando cierto tipo de intuición a la hora de elegir una tecnología u otra, de tomar ciertas decisiones de diseño e incluso de oler cuándo alguien puede encajar mejor en un equipo o en otro. Cuando has tocado en profundidad cierto tipo de sistemas grandes, amplías, digamos, tu visión a la hora de afrontar nuevos.

Es cierto que a todo el mundo le gusta trabajar en cierta zona de confort donde lo tiene todo controlado, pero yo comprobé hace mucho que permanecer demasiado tiempo en ella es perjudicial para una profesión tan volátil como compleja: en menos tiempo del que te puedes dar cuenta, terminas convirtiéndote en un dinosaurio que, fuera de tu empresa, lo va a tener difícil para encajar.

Sí, puedes llevar quince años en una multinacional y al mismo tiempo ser un dinosaurio tecnológico. Y no hay nada de malo en ello, pero tenlo en cuenta cuando de un día para otro tengas que salir de esa zona de confort (la única) que has conocido durante tanto tiempo.

Esto es especialmente problemático para los perfiles técnicos que pasan a gestionar como única actividad y al cabo de uno o dos años, pierden rápidamente la mayoría de sus habilidades técnicas.

Nadie puede decir que tenga quince años de experiencia cuando te has pasado todo ese tiempo actualizando sistemas operativos, o manteniendo una aplicación hecha en cobol o C, o programando cierto tipo de dispositivos y, a continuación, decir con la boca llena los años que llevas en el sector, cuando éste es, para ti, en realidad, bastante pequeño.

En otras palabras: la cantidad (tiempo), importa, claro, pero la calidad (experiencia diversa), es mucho más importante y, lo ideal es que ambas coincidan a la vez: tiempo más experiencia real en muchos y diversos proyectos.

Si eres un dinosaurio tecnológico (tan solo es una metáfora), no hay nada de malo en ello, claro, pero sí resulta peligroso cuando en algún momento tienes que pivotar de lugar, te largan de un día para otro o te ves obligado a montártelo por tu cuenta.

También he comprobado cómo trabajando en diversas áreas muy diferentes eres capaz de enriquecer un nuevo proyecto que comienzas y del que aún no tienes ni idea de cómo desarrollar. Por ejemplo, el mecanismo de extensibilidad de Drupal u entornos similares, es un buen ejemplo de arquitectura que se puede replicar en otro tipo de sistemas; un módulo tan simple y útil como Squel, te puede mostrar lo útil que resulta encadenar llamadas cuando tienes que realizar el cliente de una API cuyo propósito es totalmente diferente; el conocer bien varios frameworks, te puede dar idea de cómo enfocarlo mejor cuando eres tú el que tiene que tomar decisiones de diseño al desarrollar uno nuevo.

Pero lo que no sirve es decir que llevas quince años desarrollando aplicaciones web basadas en Wordpress y poco más, o desarrollando firmware para remotas de control, o mucho tiempo desarrollando el mismo sistema para la misma compañía, o manteniendo un proyecto que lleva una eternidad funcionando para el mismo cliente, y a la vez indicarlo con cierto aire de autosuficiencia. No te engañes. Quizá no te des cuenta, pero tu experiencia entonces es bastante limitada, a pesar del tiempo que haya pasado.

Como parte de El Libro Práctico del Programador Ágil, he incluido un pequeño capítulo sobre un tema sobre el que he reflexionado mucho a lo largo de los años. En ocasiones, las cosas no son como parecen, y, sobre todo, en el desarrollo de software hay que hacer un gran trabajo de pedagogía a gestores de proyectos que no han programado lo suficiente, para hacerles comprender ciertos aspectos inherentes a la programación que no dejan de ser algo sutiles.

Las apreciaciones que voy a indicar a continuación, en un principio, pueden ir en contra de la intuición acerca de nuestra actividad como desarrolladores de software. Muchos de los errores que cometemos en nuestro desempeño profesional mientras programamos y diseñamos aplicaciones, derivan de no comprender ciertas sutilezas en relación a la producción de código de calidad.

Idea contraintuitiva #1

Es difícil hacer software simple

No podemos caer en el error de pensar que cuanto más complejo es algo, más difícil es, o peor aún, más y mejores habilidades tiene su autor. En software, la verdadera habilidad y excelencia consiste en encontrar una solución sencilla a un problema complejo. Es algo que para mí siempre me causó admiración comprobar cómo se encuentran soluciones entendibles y cómo resuelven problemas complejos. Nada peor que un sobrediseño innecesario, o añadir complejidad por no pararse unos minutos a buscar una solución más sencilla. Para ello, debemos tener siempre presente esta idea de la sencillez mientras programamos.

Idea contraintuitiva #2

El diseño de una solución también evoluciona y crece, así como su arquitectura

En desarrollo ágil (programar para que nuestra aplicación acepte cambios más fácilmente), se suele decir que el diseño emerge a medida que se implementan nuevos requisitos, y así es. Lo contrario es establecer un diseño al comienzo de la aplicación y tratar de mantenerlo rígido a toda costa. De ningún modo: el diseño hay que cambiarlo para ajustar a la nueva funcionalidad que se va incorporando. Se mejora la calidad del código de forma continua, también su diseño.

Idea contraintuitiva #3

Hacer tests aumenta la productividad

Cuántas veces he oído lo mismo: “no tengo tiempo para hacer tests”. Decir esto no es profesional, ya que respaldar con tests nuestro código no es una tarea ajena al desarrollo de software, sino inherente a ella. Contrariamente a lo que pueda parecer, escribir tests reduce el tiempo dedicado a detectar y corregir bugs, además de darle solidez a la aplicación.

Idea contraintuitiva #4

Hacer tests es un modo de documentación de nuestro proyecto

El exceso de comentarios insertados a lo largo del código es un síntoma de la pobreza del mismo. En ocasiones, contadas, son necesarios, pero en realidad su sobreutilización revela que el código no es lo suficientemente simple y fácil de entender. En relación a los tests, ¿cómo podemos aprender cómo usar una clase, una librería, un módulo, etc.? Efectivamente, con los tests que los respaldan. Nada mejor que aprender cómo se utiliza algo que con un código que lo prueba.

Idea contraintuitiva #5

Hacer tests obliga en cierta medida a realizar un mejor diseño

Plantea una aplicación monolítica para hacer cualquier cosa que se te ocurra. Te saldrá, con toda seguridad, una serie de clases con métodos muy largos, acoplados y rígidos, aunque funcione y realice su propósito… En este libro queremos aprender a programar para que nuestra aplicación acepte cambios más fácilmente y sea más mantenible, ¿no es así?

Esa aplicación monolítica solo podrá ser probada manualmente, poco más. Si quieres introducir tests en ella, pronto te darás cuenta de que su estructura y la relación de sus componentes (diseño) debe cambiar: debe mejorar. Hacer tests te obliga, en cierto modo, a crear un diseño mejor.

Idea contraintuitiva #6

La optimización del código es una tarea continua

Optimizar código para se ejecute con mejor rendimiento es una tarea habitual, sobre todo para aquellas partes de la aplicación que se ejecutan más frecuentemente. Sin embargo, dejar esa actividad para el final es un error. Del mismo modo que incluimos en nuestra práctica y rutina habitual de desarrollo el crear tests para respaldar nuestro trabajo, también debemos incluir esas pequeñas optimizaciones que mejoran el rendimiento del mismo, siempre y cuando no se sacrifique la simplicidad y su legibilidad.

Del mismo modo en que mejoramos la calidad del código y su diseño mediante pequeños pasos, ocurre lo mismo con su optimización.

Idea contraintuitiva #7

El rendimiento de una aplicación no solo se consigue con más hardware, también con un mejor diseño

La solución rápida cuando se presentan problemas de rendimiento, consiste en añadir más hierro al sistema de producción donde se ejecuta la aplicación: más memoria para el engine de la base de datos, más discos SSD, balanceo entre sevidores, etc. Puede que sea necesario, pero, en ocasiones ese coste lo que viene es a tapar una arquitectura, diseño y una solución pobre o ineficiente. He visto quemar, literalmente, miles de euros, en hardware para una solución con una arquitectura errónea y mal planteada.

Idea contraintuitiva #8

El diseño de las bases de datos, como cualquier otro asset de un proyecto software, también está sujeto a una mejora continua

Todos los elementos de una aplicación son susceptibles de mejora: desde archivos CSS, html, scripts de front-end en javascript hasta soluciones de más alto invel en C#. Absolutamente todo. Las bases de datos, su diseño, no escapan a esta mejora y evolución continuas.  Si mantenemos su rigidez inicial, o el modo en que se planteó inicialmente la base de datos, tendremos el problema de tratar de meter con calzador la nueva funcionalidad requerida.

Idea contraintuitiva #9

Una gran mejora siempre es producto de micro mejoras

En software se produce un efecto acumulativo cuando introducimos pequeños cambios de manera continuada: simples refactorings (como los descritos en este libro), mejoras minúsculas en la legibilidad del código siguiendo las técnicas de código limpio, mejoras en el diseño, mejoras insignificantes en la organización del proyecto, etc. Con el tiempo se van acumulando cientos de pequeños cambios que supondrán realmente aumentar la calidad y la mantenibilidad de la aplicación. Además, muchas de estas mejoras son mini tareas que se pueden realizar en minutos, como mejorar los nombres de variables, simplificar un método, extraer código duplicado, agregar un par de test unitarios, etc.


Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

Hace ya cuatro años que publiqué El Libro Negro del Programador, con una segunda revisión de ese trabajo el año anterior. Desde entonces, no han parado de aumentar las reviews en Amazon así como los mensajes que me llegan directamente desde muchas partes del mundo.

Y todo esto, en definitiva, lo que me ha hecho es comprender que las problemáticas que se describen en el libro forman parte del sector en general, independientemente del país donde trabajes o del tipo de compañía.

Mala organización, software que se desarrolla sin cultura de tests, gestores de proyecto que no conocen la idiosincrasia inherente a un proyecto software, desarrolladores demasiado individualistas, ausencia de cultura de código limpio y de conocimiento de técnicas de refactoring, etc. Todo esto no ocurre más en el mundo castellano parlante, ni mucho menos, tan solo hay que ver algunos repositorios de código en GitHub, algunos de ellos muy populares.

He trabajado en proyectos internacionales con compañías de Suecia, USA y países de Oriente Medio y de Sudamérica, y puedo decir que lo que he visto con frecuencia viene a ser un poco más de lo mismo, las mismas dinámicas y problemas similares, salvo algunas excepciones de las que aprendí muchísimo y fueron fuentes de inspiración con las que tuve la suerte de cruzarme.

Por tanto, he lanzado una nueva edición de El Libro Negro del Programador pero esta vez en inglés, confiando en que sea de la misma ayuda para desarrolladores angloparlantes que para los lectores en español.

Y porque vivimos en un mercado global en donde todo lo digital y el conocimiento apenas tiene fronteras, y porque en el sector de la tecnología, el inglés es el idioma estándar de facto.

Confío en que este nuevo trabajo sea de la misma utilidad para todos los lectores que no hablan español pero sí leen en inglés y que funcione igual de bien tal y como lo ha hecho El Libro Negro del Programador en estos años.

A partir de ahora me propongo ir añadiendo contenido en inglés a mi web personal.

The Black Book of the Programmer

 

Lo he visto en demasiadas ocasiones: una aplicación es concebida inicialmente para realizar un conjunto reducido de tareas, pero, con el tiempo, se va tratando de incluir más y más funcionalidad. Lo que debería ser un éxito (se pide nueva funcionalidad porque lo anterior funciona y es de utilidad) se termina convirtiendo en una auténtica patata caliente imposible de mantener y para la que cualquier nuevo cambio cuesta más y más esfuerzo (y dinero) en introducirse.

También lo he visto (y sufrido) demasiadas veces: los responsables de esas aplicaciones son reacios a reconocer el problema y suelen echar balones fuera y mantenerse dentro de cierto caos antes de asumir profesionalmente que se ha alcanzado un punto crítico en el que hay que tomar decisiones desagradables.

El resultado es siempre el mismo: después de mucha frustración, se llega inevitablemente a la conclusión de que hay que rehacer partes completas de la aplicación cuando no tirarla a la basura completamente y comenzar desde cero.

No podemos perder la perspectiva: si se trata de un proyecto con cierto carácter lúdico, un repositorio que apenas mantienes en Github o Codeplex, bien, no pasa nada, salvo el tiempo que se haya podido perder, pero si se trata de un proyecto empresarial, todo lo anterior se traduce en costes dolorosos y, seguramente, un equipo frustrado por trabajar en una aplicación difícil.

Este es un mantra que conviene no olvidar nunca: todo software requerirá de cambios inevitablemente (y el fundamento del enfoque ágil). Si no se diseña para admitirlos, entonces nos encontraremos tarde o temprano con una aplicación corrupta y el escenario descrito párrafos más arriba.

La buena noticia es que se puede evitar, trabajando desde el inicio del proyecto en la línea correcta.

Pero, ¿por qué llega a corromperse una aplicación con el paso del tiempo a medida que la hacemos cambiar? A continuación enumero una lista de algunas de la razones:

  • Una aplicación es concebida inicialmente como simple o pequeña y se le obliga a crecer de forma muy rápida y descontrolada.
  • No existe metodología a la hora de ir introduciendo nuevos cambios: los requisitos llegan de un día para otro, se vuelve atrás con frecuencia, no hay planificación y cultura de testing o validación de la aplicación antes de ser entregada, abonando el terreno para el caos.
  • Los requisitos no son claros: la traducción de los requisitos de negocio a los requisitos técnicos no se realiza con exactitud y la suficiente comprensión. El resultado es que se implementa funcionalidad que no es exactamente la que se quería, produciendo una cascada de cambios y, posiblemente, dejando código muerto y obsoleto a medida que eso ocurre, ensuciando la solución.
  • Se utiliza una dispersión de tecnologías que dificulta la evolución de la aplicación. Para programar bien y de forma mantenible, hay que conocer bien las librerías y frameworks que se utilizan; un exceso de estos en la misma aplicación provoca confusión y es más difícil de llevar. Además, si se usan librerías complejas, esto ofuscará la solución.
  • No se dedica tiempo a mejorar lo que ya existe, aunque funcione. El desarrollo de software es en cierta medida incremental: construimos nueva funcionalidad sobre lo ya existente o del mismo modo que lo que ya existe. Hay que tener siempre la actitud de mejorar continuamente lo que ya hay.
  • Se intenta mantener código obsoleto, mal diseñado, mal probado, a toda costa. A veces cuesta trabajo eliminar partes de la aplicación porque recordamos el esfuerzo que nos llevó hacerlas, o por simple pereza, pero arrastrar algo que no está del todo bien es perjudicial: podemos decir que lo que eliminamos, en realidad, nos sirvió para aprender a hacerlo mejor.
  • No se tiene en cuenta que no solo se mejora el código en sí, también el diseño y la organización del proyecto.
  • No se siguen prácticas de código limpio y de refactoring de forma continuada.
  • El proyecto no tiene tests o la batería de tests es insuficiente con una cobertura de código baja. Esto provoca que no sepamos cuanto antes qué bugs introducimos al hacer cambios: cuanto antes se detecte un bug, más fácil y sencillo será corregirlo. Además, incluir tests obliga a diseñar la aplicación con mejor estructura (software testeable), alejándonos de enfoques monolíticos y rígidos.
  • El diseño (si es que existe) es pobre.
  • Y, por supuesto, ocurre parte o todo lo que describro en El Libro Negro del Programador

​Lo bien o lo mal que hagamos todo lo anterior, hará que lleguemos antes o después a la barrera de inmantenibilidad, tal y como describe la curva o Ley de Boehm, que viene a indicar el coste incremental de corregir errores desde una fase temprana del proyecto o en una fase tardía (cuando ya el software es... demasiado corrupto):

Boehm's Law

Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

¿Cómo podemos discernir que una aplicación es de mayor calidad que otra?

Lejos de plantear una definición demasiado académica y siendo pragmáticos, podemos decir que un software es de calidad no solo cuando cumple correctamente la funcionalidad requerida, además, lo consideramos de mejor calidad cuando el coste de su mantenimiento es bajo y la dificultad para introducir nuevos cambios (nuevos requisitos) también es baja o trivial.

Fácil de decir, pero en cierta medida, difícil de conseguir. Esta es la definición de calidad de software que, en mi opinión, es más interesante considerar en el día a día como programador en cualquier compañía.

La mayoría de los desarrolladores, por falta de experiencia, o bien por presiones en tiempo o ausencia de disciplina, nos quedamos atascados en ese primer aspecto de la calidad que comentamos en el párrafo anterior: cumplir la funcionalidad y punto, dejando la implementación de la funcionalidad X del primer modo en que la hemos escrito y resuelto. Sin embargo, ya sabemos que en cualquier negocio o proyecto, salvo excepciones muy contadas, a nuestro código se le va a requerir cambiar, sí o sí. Precisamente de esa realidad (todo software va a sufrir cambios), nació el movimiento de software ágil como forma de abordar mejor el código que escribimos, dando a pie a técnicas, al concepto de diseño ágil, etc.

Métete esto bien en la cabeza: debemos escribir código pensando en que sufrirá cambios necesariamente. La capacidad de aceptarlos determinará el coste de mantenerlo e incluso el éxito o fracaso del proyecto.

Recapitulemos: no programamos únicamente para cumplir con cierta funcionalidad que se exige en la aplicación hoy, también para hacer funcionar un negocio (que es el que paga en última instancia), y pocos negocios hay estáticos y que no tengan que cambiar, optimizarse o mejorar continuamente.

En este sentido, es fácil determinar si una aplicación es de calidad o no, tan solo tenemos que mirar los siguientes aspectos:

  • El código es simple (fácil de entender). La habilidad de un buen programador reside básicamente en encontrar soluciones sencillas a problemas que no lo son tanto.
  • También es legible (fácil de leer y de seguir). El código debe ser fácil de leer por cualquier miembro del equipo y  debe poder ser asumido con facilidad por cualquier nuevo miembro que se incorpore.
  • Existen tests que proporcionan una cobertura suficiente, esto es, un porcentaje alto de todo el código de la aplicación está cubierta por pruebas. El testing es un tema extraordinariamente amplio de modo que un tester en condiciones tiene habilidades técnicas diferentes que un desarrollador. Digamos que, con los pies en la tierra y siendo prácticos, que nuestro proyecto debe tener al menos una buena batería de tests unitarios y de integración.
  • El diseño y el código es homogéneo y coherente. No programamos del primer modo en que se nos ocurre solucionar algo, sino que esta solución debe mantener el diseño de la misma y estar alineada con el resto del código de la aplicación en estilo, uso de librerías externas, normas consensuadas de hacer las cosas, etc. Nada peor que identificar una parte específica de un proyecto en el que se reconoce la mano concreta de un compañero.
  • El desarrollador dedica la mayor parte de su tiempo a añadir nueva funcionalidad, no a corregir bugs. Si pasamos mucho tiempo detectando o corrigiendo errores, entonces ya sabemos que la aplicación se aleja de la definición de calidad que hemos dado más arriba y, por tanto, hay mucho trabajo para mejorarla.
  • A producción solo llegan (si llegan) pequeños defectos, nunca errores críticos. No es profesional liberar una versión de nuestro proyecto de modo que en explotación presente errores graves que impidan el buen funcionamiento de la actividad que soporta.
  • Las métricas más básicas dan buenos valores. Existen muchas métricas para evaluar diferentes aspectos del código, pero algunas básicas son fáciles de obtener y nos pueden ayudar a detectar ciertos problemas, como el número de líneas por método, la complejidad ciclomática, detección de código que nunca se ejecuta, etc

Nota: este artículo es es un resumen y forma parte del proyecto en desarrollo El Libro Práctico del Programador Ágil. Lanzamiento en julio 2018.


 

Páginas

Archivo

Trabajo en...

Mis novelas...