Ha pasado ya un tiempo desde que no publico nada nuevo en mi web personal y profesional (que es ésta, claro, y que, por cierto, ahora mismo estoy modernizando en otra totalmente diferente), y es que en el último año y medio, he estado muy pero que muy ocupado. Tanto ha sido así, que apenas he tenido energía para trabajar en un nuevo libro ni para dedicarle algo de tiempo a mis proyectos personales.

Como Engineering Manager de una multinacional suiza con oficina en la ciudad donde vivo, he vuelto a acumular experiencias maravillosas, conocer gente inteligente y encantadora, incluso conocer una industria que desconocía totalmente (la del betting y el iGaming), entrar de nuevo en la dinámica estresante de lanzar un proyecto muy importante, gestionar en situaciones difíciles en ocasiones, motivar cuando el ánimo caía en los equipos y la presión era asfixiante y también tratar de aportar mi granito de arena positivo en todo aquello. Pero tuve que bajarme de ese proyecto, me temo.

Quizá es una cuestión de edad, de los años que vamos cumpliendo, pero llega un momento en que te planteas si lo que haces cada día está alineado con tu propósito, tu propósito vital, digo.

Ya sabemos que la vida tiene que ser un equilibrio: el te tus relaciones (tu pareja, hijos, familia, vida social, etc.), tu salud (ejercicio, comida sana), tu higiene mental (esa paz interior que en el fondo es lo que todos buscamos de un modo u otro) y, cómo no, la actividad profesional a la que te dedicas.

Cuando ves que ésta se aleja cada vez más de aquello que más te interesa, o cuando estás deseando que llegue el fin de semana para leer esto y aquello (en temas que no tienen nada que ver con los de la empresa para la que trabajas), comienza a crearse una distancia entre lo que haces y lo que quieres, y cuando esa distancia va aumentando, sientes una presión insoportable y tu motivación diaria se va diluyendo hasta desaparecer. Cuando eso ocurre, puede que ya no tengas ni la motivación suficiente para desempeñar tu trabajo al 110% (que es lo mínimo que nos podemos exigir).

Como digo, puede que al cumplir más años y acumular ya unos treinta de experiencia profesional, ya no te conformas con un proyecto que no te apasiona, aunque se te retribuya de manera buena o excelente. Lo que quieres es dotar de sentido al proyecto para el que pasas más de 40 horas a la semana trabajando y tener un impacto positivo en tu sector, en tu mercado, y por qué no, en el mundo. 

Al menos estas son las cuestiones que me planteo en los últimos años, de ahí que para mí sea tan satisfactorio ver cómo mis libros se venden cada día, porque entiendo que con ellos estoy ayudando a mejorar algún aspecto profesional (y personal) de la vida de quien los compra, nada más satisfactorio que esto. No hace mucho calculé (es difícil hacerlo, de modo que es solo una estimación), que desde que en el 2014 publiqué El Libro Negro del Programador, mi primer libro, se habrán vendido unas 40000 copias de todos los que he publicado (más las lecturas piratas, claro está). Esto es, con ese trabajo difícil y arduo que es escribir, estructurar y publicar un libro, hay miles de personas que se han beneficiado.

Este último año y medio he vuelto a comprobar situaciones y dinámicas que he descrito hasta la saciedad en mis libros, buenas, normales y también tóxicas. Pero, sobre todo, he vuelto a comprobar que por mucho trabajo de gestión que hagas, no se puede dejar de tener contacto con la base de nuestra profesión, esto eso, programar y programar en proyectos personales, utilizar herramientas, conocer plataformas, pulir procedimientos y flujos de trabajo, etc.

Esto es, hay que estar siempre afilando el hacha, algo que siempre he hecho como manager, jefe de proyecto o director de departamento (llámalo como quieras), con un doble esfuerzo por mi parte, y porque reconozco que amo mi profesión, que siento adicción cuando te sube la adrenalina cuando publicas un nuevo proyecto y porque programar es a nuestra profesión lo que hacer una salsa cualquiera para el mejor chef (se entiende la metáfora, ¿no? :-) ).

De lo contrario, echarás la vista atrás en un tiempo y verás cómo las habilidades que tenías hace años, las has perdido, y quién sabe, lo mismo tienes que asumirlas de nuevo para un nuevo reto profesional.

Estos últimos meses (desde el momento en que escribo esto), además de descansar después de unos años con demasiados cambios (y hasta mudanzas :-) ), leyendo mucho, muchísimo, cuidándome más que nunca, terminando la certificación de Bitcoin Talents (programa en el que me admitieron a finales del año pasado, de la Frankfurt School Blockchain Center), retomando proyectos como Mantra, construyendo algunas aplicaciones, instalando nodos de Bitcoin y preparando mi próxima publicación y, sin prisas, buscando un proyecto nacional o internacional donde pueda tener esa sensación de aportación que es para mí la base de mi satisfacción profesional.

Esto es para mí afilar el hacha.

 

 

Estos últimos meses he estado introduciendo muchas mejoras en el core de Mantra, plantenado el camino para que en los componentes de un proyecto se puedan introducir módulos en formato WebAssembly y programados en Rust, sin que el ciclo de vida del componente se haga más complejo; trabajo en este camino porque precisamente Mantra está planteado para implementar aplicaciones de alto rendimiento y escalables, por la propia naturaleza del framework y el paradigma de desarrollo que sigue.

Llevo profundizando en estas tecnologías desde que comenzó el año, y aunque a lo largo de mi carrera profesional he visto ya varias promesas que afirmaban que "lo cambiarían todo" (escondiendo, seguramente, algún propósito comercial, claro está), para desaparecer en el olvido años más tarde, no puedo decir lo mismo de WebAssembly en general y Rust como lenguaje en particular.

WebAssemblyWebAssembly

¿Por qué? Te lo explico a continuación.

En software ocurre exactamente lo mismo que en otras actividades: es cierto que en ocasiones, una moda pasajera impone que se usen tecnologías (o ciertas librerías o frameworks, que no siempre se distingue bien entre una cosa y la otra) que, en mi opinión, no deberían tener el puesto destacado que tienen, pero en otras, la enorme utilidad de algo hace que explote su uso, porque precisamente viene a llenar un vacío en la industria o a resolver un problema importante.

Eso es precisamente lo que pienso de WebAssembly y Rust que, al igual que el resto de tecnologías, ni resuelven todos los problemas ni son un cajón de sastre para hacer de todo, tienen su espacio y sus casos de uso.

Éstos se basan principalmente en aplicaciones (cada vez con mayor demanda y auge) que necesitan de un rendimiento mucho mayor (cercano al de las máquinas nativas donde se ejecutan) y que no se puede obtener por diversos motivos con otros entornos de programación, pero añadiendo también otras características que, sinceramente, cuando he ido profundizando en ellas me he quedado sorprendido: mayor seguridad por la propia naturaleza de Rust, no hay necesidad de que exista un recolector de memoria (sí, lee esto de nuevo) y, lo más importante, portabilidad a diferentes arquitecturas hardware y sistemas operativos, nada más y nada menos.

Mientras que WebAssembly es un lenguaje de bajo nivel similar al ensamblador (tranquilo, que no hace falta volver a programar en ensamblador), y que genera un formato binario portable y extraordinariamente compacto cuando se compila (generando archivos wasm), que puede ser ejecutado los navegadores de mayor use pero también en otros entornos, Rust es un lenguaje diseñado desde su base para generar código eficiente, con un uso de la memoria seguro y en contextos de threads también seguros, y que recuerda mucho a C  y C++ aunque no es de tan bajo nivel como éstos.

Rust no es un lenguaje escribir para cualquier tipo de aplicación, sino más bien y dada su naturaleza, para programar sistemas: drivers para dispositivos embebidos, sistemas operativos, procesamiento de imágenes y de video, internetworking, virtualización e incluso para programar otros lenguajes de mayor nivel. Otra definición para Rust: es un lenguaje para la programación concurrente sin la dificultad que implica esto en lenguajes como C o C++ y con el rendimiento de éstos.

Por decirlo de alguna manera, WebAssembly empaqueta en ese código binario portable y eficiente el resultado de aplicaciones escritas en Rust (pero también en C y C++).

WebAssembly está fuertemente apoyado por grandes de la industria, como Mozilla, y en mi opinión, aunque cuenta ya con unos años de desarrollo, su uso y aplicaciones se van a extender extraordinariamente en el futuro: tratamiento de imágenes y de video, aplicaciones en tiempo real que manejan grandes volúmenes de datos, aplicaciones embebidas para dispositivos IoT, FaaS (functions as a service), gaming (puesto que éstos son aplicaciones que también requieren de un mayor rendimiento), aplicaciones multiplataforma, etc.

Por otra parte, la curva de aprendizaje del tooling para WebAssembly así como de Rust, en mi opinión es baja, sobre todo si ya has tenido una experiencia previa con entornos basados en C o C++ y has programado mucho a bajo nivel. En una etapa laboral anterior, estuve 12 años programando en C++, de modo que veo en Rust muchas características similares que me llenan de cierta extraña nostalgia :-)

En software frecuentemente se lanzan tecnologías que terminan resultando efímeras (y que seguramente nos ha costado muchas horas aprender), pero WebAssembly y Rust han llegado para quedarse, tan solo hay que ver qué empresas lo usan y lo apoyan y están involucradas en su desarrollo.

Mantra

Un artículo de Rafa G. Blanes

O lees o escribes, o consumes o produces, o usas tecnología de otros o la creas. Ya sabes que lo más complicado está en lo segundo (escribir, producir y crear) y no comprendo por qué pasamos los desarrolladores de software más tiempo en lo primero que en esto último.

Es especialmente emocionante cuando sacas a la luz algo en lo que has estado trabajando muchísimo tiempo (años).

Me pasa con todos y cada uno de mis libros, cuando por fin ves el último trabajo en todas las tiendas de Amazon y el resto de plataformas (como esta pequeña aportación que he lanzado recientemente sobre Bitcoin), cuando publico un nuevo proyecto o cuando por fin paso a producción el realizado para algún cliente.

Desde hace unos meses, ya puedo decir que existe una release de Mantra suficientemente madura como para poder ser usada en proyectos en producción.

Para lo bueno y para lo malo, como desarrador profesional de software así como responsable de equipos y de proyectos desde hace más años de los que recuerdo, me ha tocado a menudo trabajar en proyectos más bien grandes y complejos y que, a lo largo de su ciclo de vida, han tenido que evolucionar mucho con bastante dificultad.

Del mismo modo, también me han contratado en ocasiones para evaluar la calidad de un proyecto software y recetar qué hay que mejorar para que la bola de barro (deuda técnica) no siga creciendo hasta hacer el proyecto inviable, inmanejable o inmantenible, cuando no se ha tenido que tirar todo a la basura y comenzar de nuevo, para espanto de los directivos y frustración de los desarrolladores. Esto no solo suele ocurrir por falta de profesionalidad en el código, también por déficits organizativos, entre otras cuestiones.

Te aseguro que detectar todo lo anterior no es ni fácil ni sencillo.

Esto es, conozco de primera mano por qué el software tiende a corromperse, cómo y por qué se acumula deuda técnica y cuáles son los malos hábitos de nosotros los desarrolladores que hace que un proyecto sea costoso de mantener, y también, tal y como digo, los malos hábitos organizativos que contribuyen a todo lo anterior.

Si has leído alguno de mis libros, sabrás ya que hablo de estos temas continuamente y en profundidad en ellos.

Y lo sé porque yo soy el primero que he cometido (y sufrido) todos los errores que se puedan cometer, pero siempre con el propósito de no comenter el mismo error más de una vez...

No en vano, uno de mis libros ("Legacy Code: Cómo modernizar en catorce pasos código heredado o proyectos software que han crecido demasiado rápido"), sugiere cómo mejorar en un conjunto de pasos la calidad de un proyecto software heredado y que hay que modernizar.

Mantra es un framework basado en Node.js que obliga a estructurar correctamente un proyecto, en base a una componetización radical y un desacoplamiento extremo entre ellos, permitiendo, a la vez, una alta testeabilidad y reusabilidad de todos y cada uno de los componentes que forman parte de un proyecto, entre muchas otras características.

Mantra no nace para competir con otros propuestas que existen desde hace mucho más tiempo (como Next.js, y que me encanta, por cierto), sino para dar respuesta a lo que yo considero que es una forma viable de enfocar el desarrollo de software para minimizar esa deuda técnica que tanto daño hace a la competivividad de las empresas, especialmente en proyectos de gran tamaño, que evolucionarán mucho, de alto rendimiento y escalables y que tienen que ser lo más competitivos posible.

Por decirlo de algún modo y sin que suene especialmente pretencioso: Mantra implementa un paradigma de desarrollo de software.

El desarrollo de un proyecto con Mantra sigue una serie de principios que he estructurado de la mejor manera posible en un whitepaper que puedes leer en inglés y en español.

Quizá, el whitepaper en el que se basa Mantra te sorprenda, porque, en realidad, más que identificar unos principios a seguir, se trata en verdad de un cambio de paradigma para enfocar el desarrollo de proyectos profesionales, grandes, evolucionables y escalables. 

Es mi pequeña contribución a la ingeniería del software aunque, créeme, muchos de esos principios son, sencillamente, buenas prácticas bien conocidas en nuestro sector pero que he agrupado en un conjunto coherente y que se implementa en Mantra para que los proyectos puedan crecer y evolucionar (con requisitos aún desconocidos) sin acumular deuda técnica.

Algunos de estos principios, incluyen:

  • Componetización radical: un componente es la pieza fundamental de código de un proyecto y, por definición, es pequeño y reutilizable, apenas unos cientos de líneas de código.
  • Un componente implementa una funcionalidad muy específica y la expone al resto del proyecto.
  • Por definición, un componente está totalmente desacoplado de otro (las dependencias son blandas y no duras).
  • La funcionalidad de alto nivel se implementa mediante orquestación de funcionalidad de bajo nivel.
  • La persistencia de datos de un componente es transparente al mismo y no supone un vínculo fuerte.
  • Un componente define modelos de datos minimalistas (apenas una, dos o tres entidades). Sí, leelo bien, nada de bases de datos grandes y acopladas, imposibles de mantener, migrar y evolucionar. Es más, Mantra permite aplicaciones multirepositorios (que usan varias fuentes de datos de forma transparente).
  • Un proyecto está basado en un conjunto de aplicaciones que se comunican entre ellas.
  • Las migraciones de un proyecto son frecuentes e incrementales.
  • etc.

Las consecuencias prácticas de aplicar los principios anteriores son increíbles: proyectos evolucionables, sencillos y menos costosos de mantener, mayor reusabilidad, mejor testing y escalabilidad.

Con Mantra he construido ya varios proyectos para diversos clientes, incluidos Hub de Libros así como el mismo site del proyecto, claro está.

Y funciona: el esfuerzo para la evolución de cada proyecto (implementación de nuevos requisitos) es pequeño si se han seguido los conceptos anteriores, la mantenibilidad es extraordinaria y la satisfacción de desarrollador alta porque pasamos la mayor parte del tiempo... implementando funcionalidad o modificando la existente.

Aunque ya se puede usar libremente, Mantra es un proyecto más ambicioso en el que iremos publicando componentes descargables, seguros y probados, con funcionalidad habitual así como proyectos completos que puedan ser puntos de partida para proyectos finales específicos.

Sinceramente, estoy entusiasmado con Mantra, creo que es el proyecto más complejo que he realizado nunca y confío en poder dedicar gran parte de mi tiempo profesional a él.

¿Cómo aprender a realizar aplicaciones con Mantra?

La curva de aprendizaje es extraordinariamente corta.

Se ha hecho un gran esfuerzo en crear una documentación exhaustiva y clara (de momento solo en inglés), y, además, continuamente se están publicando proyectos de demostración mostrando cómo realizar tareas concretas, además de la constante publicación de how-tos indicando en breves artículos cómo hacer tareas concretas.

Mantra, como cualquier proyecto software, es un proyecto en evolución continua, en el que constantemente se están introduciendo mejoras de rendimiento y en la funcionalidad existente, pero con el compromiso de que el usuario y la empresa que usa Mantra, no tenga que pagar un coste por migraciones a las nuevas releases que vayamos lanzando, porque, insisto, uno de los objetivos que tiene Mantra es reducir el coste del desarrollo de aplicaciones profesionales para que sean más competitivas, y esto se consigue desde diversos ángulos.

Como framework, fue surgiendo poco a poco de forma natural al trabajar todos estos años atrás en proyectos basados en Node.js y sin convencerme del todo otros frameworks que ya existen, sencillamente por no poder implementar fácilmente y de forma natural los principios anteriores.

Como CTO de Mantra, confío en que esta aportación sea de una gran utilidad para nuestro sector, siempre en evolución y siempre con ese espíritu de kaizen de mejora continua.

Nada es más excitante cuando uno trabaja en algo durante mucho tiempo y por fin está listo para que salga a la luz.

Llevo varios años entusiasmado por todo lo relacionado con Bitcoin en particular y el mundo cripto en general, y lo que más me entusiasma de todo esto son las profundas implicaciones y el gran impacto que van a tener (tienen ya) en la sociedad y en nuestra relación con "el dinero", y así lo creo.

Para mí, estamos en un momento de cambio, aunque no se hable de ello continuamente, tan solo noticias a veces entusiastas y en otras ocasiones alarmantes, de un cambio tan profundo como fue la aparición al comienzo de Internet y su expansión exponencial años más tarde. Ahora toca algo igual o más importante: modernizar el dinero, ni más ni menos, porque Bitcoin es el "Internet del dinero".

Mi primer contacto con Bitcoin fue en el 2013, tal y como comento en la introducción de este nuevo libro, pero perdí el interés hasta años más tarde, en el 2018; a medida que leía y leía y profundizaba en Bitcoin y el mundo cripto, fui poco a poco comprendiendo las implicaciones y la importancia de todo esto.

Pensé entonces que llegaba tarde a la fiesta, para descubrir que, en realidad, aún estamos en una fase de adopción muy temprana.

Me he leído todo lo que ha caído en mis manos sobre Bitcoin y temas relacionados (libros que incluyo en la bibliografía) y raro es el día en que no lea un artículo o dedique un rato a este sector emergente. Es más, sigo en LinkedIn a numerosas empresas y profesionales que se dedican ya a esto.

También pienso que estamos ante una enorme oportunidad para los desarrolladores de software, con una demanda de profesionales que sepan de esto, solo hay que buscar las remuneraciones que se ofrecen.

Es más, comencé trabajando en un libro para enseñar a "programar servicios con Bitcoin", puesto que me he familiarizado con sus detalles técnicos y su uso, pero pronto me di cuenta de que incluso en nuestro sector, hay un gran vacío de su comprensión incluso rechazo (por falta de información, eso es lo que creo).

De modo que me propuse escribir un libro diferente de todo lo que había leía hasta entonces (demasiado académico o demasiado superificial o muy técnico), y que con él, cualquier persona sin conocimientos previos ni de Bitcoin ni siquiera con algún bagaje técnico, pudiese entender de qué va todo esto.

Esto es, este es mi primer libro para un público en general.

Tal y como digo en el libro, comprender Bitcoin requiere entender también el sistema económico actual, inflacionario por naturaleza y basado en deuda, a lo que dedico algunos capítulos. Me temo que muchos se llevarán grandes sorpresas al comprender mejor las trampas de nuestro sistema económico, con sus bondades pero también con sus defectos sistémicos.

Y es que Bitcoin nace como una alternativa a todo ello, de ahí el discurso ácido y agresivo de muchos agentes económicos, como bancos, instituciones de inversión, y hasta gobierno, etc. Claro, viene una tecnología que los deja obsoletos, inevitablemente y le quita al "poder" nada más y nada menos que la política monetaria.

Esto, ahora, puede parecer asombroso y hasta inquietante para algunos, para otros es una gran esperanza y oportunidad para la humanidad en general. No hay que irse muy lejos cuando eso del "libre intercambio de la información" que supone Internet, ponía nervioso a políticos allá por los 90 (algo que yo mismo presencié en aquella época).

Ya hay países que aceptan Bitcoin como "moneda legal", y su expansión tiene que ser inevitable. ¿Por qué? Porque sus atributos como moneda son muy superiores y no existe nada igual, del mismo modo el que correo electrónico dejó obsoleto el correo postal, por poner un ejemplo.

Jack Dorsey, el ex CEO y fundador de Twitter, dejó hace unos meses ese puesto para dedicarse totalmente a Block y fomentar Bitcoin y las finanzas descentralizadas, así que yo me pregunto que qué habrá visto como visionario en ese sector.

No sé si tienes ya una opinión sobre Bitcoin y la industria cripto que se está creando, pero te animo a leer este nuevo libro que acabo de lanzar con la ilusión de acercar esta nueva revolución a cualquiera que quiera aprender sobre ella y aprovechar todas las ventajas que tenemos ahora en esta etapa de adopción todavía temprana (aunque se estima que ya hay unos 140 millones de personas con cuentas de Bitcoin).

Buenas prácticas de diseño y de arquitectura, una buena política de testing y una metodología ágil, son necesarias pero, en ocasiones, no lo suficiente como para encontrar la mejor solución a una lógica de negocio particular, como veremos en este artículo.

Para bien o para mal, me ha tocado en los últimos años, abordar y dirigir proyectos en cierta medida complejos y escalables.

Reconozco que esta complejidad no radica exclusivamente en tener que resolver problemas ciertamente difíciles, con grandes volumenes de datos o sistemas que deben soportar grandes cargas de trabajo o usuarios, sino más bien en mantener una visión de diseño y de arquitectura suficientemente flexibles para que estas aplicaciones puedan ser mantenidas durante años, ya que, algunos de estos proyectos de los que hablo, consisten en sistemas que, por su naturaleza, una vez instalados para el cliente, se van a mantener activos durante muchísimo tiempo (incluso décadas, me atrevo a decir), debido al grado de integración y de dependencia de esos negocios con este tipo de productos.

Sin ir más lejos, uno de ellos es la Plataforma de Telegestión IRIS, que, a día de hoy, ya tiene unos ocho o nueve años de funcionamiento en diferentes instalaciones.

Como digo en ocasiones, una aplicación que va a evolucionar mucho y durar muchos años, tiene que ser construida de un modo diferente que los proyectos que se cotizan por horas, se entregan y no van a cambiar más. 

Cuando construyes aplicaciones así, te basas, lógicamente, en un conjunto de frameworks y librerías de muchos tipos (en el ejemplo que comenta, .NET, KendoUI, NInject y un larguísimo etcétera). Como cualquier otra aplicación, claro está.

No obstante, cuando implementas la funcionalidad específica del producto, en la forma de su lógica de negocio, solemos tender a implementarla ad-hoc, basada, claro está, en todos esos frameworks y librerías, como no puede ser de otra manera.

Tendemos a pensar que un framework en software consiste únicamente en eso: algo en lo que te basas para construir lo específico de un proyecto, y está bien y tiene que ser así, no hay duda de ello. Pero esa concepción de framework es demasiado limitada.

Todos los proyectos demasiado espaguetizados que he visto (e insufribles), tenían ese defecto: demasiado código explícito para resolver su lógica de negocio y ausencia absoluta de una mínima abstracción, esto es, la implementación de utilidades o reglas que permitan implementar esa lógica de negocio particular.

Programar, en cierto modo, consiste en aplicar un paradigma de trabajo que, finalmente, generará el código de una solución de una forma u otra. Por poner un ejemplo, no tiene nada que ver el diseño y la forma de resolver un problema usando orientación a objetos que si usas un lenguaje funcional. Según el lenguaje que uses, utilizarás unos artefactos u otros.

Pero no solo cambian las herramientas que usas (en la forma de sintaxis y utilidades), sino que, con ellas, tu mente aprende a abordar un problema de una forma u otra. Me explico.

Dadas unas herramientas concretas, la forma de implementar algo cambia, esto es, piensas en el modo de resolver el problema a partir de ellas. La limitación no se basa solo en lo que te ofrece un entorno de trabajo concreto (objetos, funciones, funciones lambda, ciertas APIs, etc.), sino en que adoptas un paradigma mental con el que encontrar la solución correcta.

De ahí que para mucha gente acostumbrada a usar lenguajes funcionales, cuando aprenden orientación a objetos, no usan correctamente este enfoque, porque siguen pensando desde la perspectiva de un lenguaje funcional (y suelen concebir las clases como simples cajas donde meter funciones relacionadas sin aprovechar todas las abstracciones y la riqueza de modelado que permite OOP).

Un artista que dispone de una paleta con muchos colores y varios tipos de pinceles, conseguirá plasmar en un lienzo una idea de cuadro con una técnica diferente que si tan solo tuviese a su disposición un bolígrafo bic y un folio A4 (es tan solo un ejemplo). El mismo pintor, claro está, pero la herramienta condiciona su forma de pensar para resolver el mismo cuadro de la forma más aproximada. Del mismo modo (y siguiendo con otro ejemplo algo peregrino), según la herramienta que tengas para clavar en una pared una puntilla, lo harás de un modo u otro: no es lo mismo hacerlo con un palo que con un martillo en condiciones, ¿no?, aunque, quizá, sería mucho mejor disponer de una pistola automática. 

En software, podemos pensar con la mentalidad de framework: cuando tienes que resolver una lógica de negocio ciertamente compleja, tendemos a implementarla directamente, en lugar de abordarla desde la mente y la perspectiva de un framework. Este modo de pensamiento y forma de abordar algunas soluciones software, se me ha revelado muy útil.

Por poner un ejemplo algo trivial e ilustrativo: supongamos que te piden implementar una aplicación para resolver la operación "2 + 5", y vas y programas el cálculo directo de esa operación. Después, a la aplicación hay que añadirle otra operación diferente, como por ejemplo "4*3 - 12", y vuelves a programar ad-hoc (explícitamente) el cálculo de esta expresión, y así, continuamente.

¿No es mejor implementar una librería a modo de calculadora genérica para resolver ese tipo de expresiones? Parece obvio, pero es así, con esas expresiones demasiado explícitas, como se suele implementar la funcionalidad de alto nivel de la mayoría de aplicaciones, cuando, en realidad, en muchos escenarios (y no digo en todos), hay una solución mejor.

Siguiendo con el ejemplo: dominio a resolver: operaciones matemáticas simples. Abstracción a implementar: calculadora (éste es tu framework para resolver tu lógica de negocio).

¿Qué será más inteligente y productivo? ¿Implementar el cálculo directo para cada tipo de operación o construir una sola vez la librería calculadora y utilizarla cada vez que haya que calcular una nueva expresión? Entiéndase el ejemplo.

Me temo que se suele implementar la lógica de negocio (esa funcionalidad que es exclusiva del dominio concreto de una aplicación) del modo anterior: escribiendo directamente el código para hacerla funcionar sin abstraer absolutamente nada, de modo que la evolución de esa aplicación consiste en escribir explícitamente cualquier nueva lógica de negocio que venga, aunque esté relacionada con la anterior.

De ahí, quizá, esos fragmentos de código con ficheros de cientos de líneas (o miles, sí, los he visto) con if, if, if, if... etc.

La abstracción consiste en darse cuenta de que dentro de la lógica de negocio de un dominio concreto, siempre se pueden encontrar patrones, logicas similares, reglas parecidas o funcionalidad sospechosamente parecida a otra.

En eso consiste la mentalidad de framework: tu trabajo ya no consiste en implementar directamente esa lógica de negocio o funcionalidad de alto nivel con código explícito ad-hoc (las expresiones matemáticas del ejemplo), sino en crear un framework que facilite implementar más fácilmente todas esas lógicas de negocio relacionadas (siguiendo con el ejemplo, crear la calculadora).

No siempre es posible aplicar esta forma de abordar el software, pero si se piensa de este modo, me atrevo a decir que las soluciones serán más robustas, más flexibles al cambio y permitirán una velocidad mayor de desarrollo.

Sin entrar en demasiado detalle, en la Plataforma de Telegestión IRIS que comentaba anteriormente, hay que gestionar muchos mensajes de diferente tipo pero similares provenientes de ciertos dispositivos que mantienen una estructura más o menos homogénea: en lugar de gestionarlos explícitamente según cada tipo (son unos cuarenta, si no recuerdo mal), creé una especie de framework para gestionar lo común de cada uno de ellos de modo que cuando los dispositivos evolucionan e incorporan uno nuevo, su inclusión en el sistema resulta trivial.

Del mismo modo, otro proyecto en el que he participaco, Picly (un servidor de imágenes al vuelo), existe un mecanismo de plugins extensible para incorporar todas las transformaciones imaginables sobre imágenes (el framework en este caso consiste en la implementación de ese gestor de plugins).

Son tan solo dos ejemplos que se me vienen a la cabeza, que, si no se hubiesen enfocado de ese modo, el desarrollo de esos dos productos habría sido muchísimo más costoso y más difícil de evolucionar y mantener.

Piensa con esta mentalidad de framework cuando tengas que resolver lógica de negocio, tus soluciones serán más robustas, menos costosas, más evolucionables y profesionales. 

Una de las características que me gusta de Kindle (el libro electrónico de Amazon), es que puedes señalar en los libros párrafos o frases. Es algo que hago habitualmente, de modo que cuando no tengo demasiadas ganas de leer, me he creado la costumbre de revisar las notas o citas que yo mismo he señalado de libros que me han gustado mucho. Imagino que esta funcionalidad la tendrán también los eReaders de otros fabricantes.

Del mismo modo, cuando lees cualquier libro, Kindle te indica qué secciones han sido más subrayadas por otros lectores, lo que te ayuda quizá a detectar ideas importantes que les han llamado la atención.

Movido por la curiosidad, estos días he comprado uno de mis libros en formato electrónico, El Libro Negro del Programador, por ser el que lleva publicado más tiempo y el que más comentarios tiene en las distintas plataformas en las que se vende, precisamente para averiguar, por simple curiosidad, si tenía muchas o pocas notas, o saber aquellos párrafos que hayan podido llamar la atención a un número suficiente de lectores como para que aparezca en el Kindle con la etiqueta de "148 han subrayado", por poner un ejemplo, como la captura que se ve a continuación:

Estas son las notas más señaladas por los lectores, frases, en mi opinión, bastante inspiradoras...:

"La genialidad de un buen desarrollador de software está en saber encontrar soluciones sencillas por complicado que sea un problema a resolver."

"El desarrollo de software es una actividad altamente creativa; por tanto, necesita de un ambiente que fomente esta actividad, no que la destruya o asfixie."

"Avanzar en los desarrollos con pruebas de calidad lo debemos incorporar a nuestro ADN  de desarrolladores."

"Antes de dar algo por finalizado, como por ejemplo, una nueva clase o una funcionalidad, nos debemos preguntar si hay algo que podamos hacer para mejorarlo o simplificarlo."

"A la capacidad de aprender de los errores y reponerse del fracaso, se llama resiliencia, y dado que trabajamos en una disciplina en la que los mecanismos para cometer errores están tan a mano y son tan etéreos, un buen desarrollador de software debe tener esta capacidad sí o sí: aprendemos más de los errores que de los éxitos."

"El arte de programar requiere de un entorno altamente creativo, lúcido, tranquilo, optimista y positivo."

"No se puede crear nada, ni software, ni arte, ni siquiera plantar un huerto buscando la excelencia en un ambiente desmotivador y nada creativo."

"En software, bello y elegante significa fácil y barato de evolucionar y de mantener."

"Somos eficaces en la medida que reutilizamos y escribimos código reutilizable. Esta es una de mis frases-mantra que repito continuamente."

Difícil describir la gratificación que uno siente cuando compruebas que algunas de tus ideas han calado en otros con ánimo de mejorar en su profesión.

 

No es lo mismo programar que desarrollar una carrera profesional como programador.

De qué hablo cuando hablo de programar (volumen 1)

Hoy es un día muy feliz para mí.

Ya está por fin disponible en Amazon un nuevo libro: "De qué hablo cuando hablo de programar: Cómo avanzar mejor y más rápido en tu carrera como desarrollador", porque escribir un proyecto software no es tan solo escribir líneas de código..., existen muchísimos más aspectos "alrededor" de esta actividad.

Se trata de una primera recopilación de los artículos de esta misma web, seleccionados entre los más visitados y enlazados, y que he revisado, corregido, mejorado y hasta algunos que he escrito de nuevo para incluirlos en este primer volumen, enriquecidos con mis experiencias de los últimos años (buenas y no tan buenas).

Solo leyendo el índice, pienso que ojalá me hubiesen hablado de todos esos temas cuando terminé mi etapa académica.

Os dejo aquí el capítulo de introducción.

Más información, en la propia sección del libro.

 

No hace mucho publiqué en GitHub un pequeño repositorio de nombre Red Entities, un simple pero eficiente object-mapper de consultas, actualmente compatible con Sqlite y varios sabores de MySql.

Lo he retomado para validarlo con la última versión de Node y además porque quiero incluir compatibilidad con PosgreSQL y Sql Server, sobre todo ahora que estoy terminando de documentar Mantra Framework para liberarlo.

Y lo curioso (e interesante), es que a pesar de haber desarrollado yo mismo ese proyecto software, me ha costado un poco de trabajo volver a asumirlo, aunque está bien soportado por tests y hasta me atrevería a decir que el diseño es sencillo pero robusto y eficiente, y tampoco es una librería de tamaño grande, ni mucho menos.

Tardé algo de tiempo de recordar cómo estaba implementado el mecanismo de inyección de dependencias, cómo lo dejé preparado todo para incluir nuevos conectores de acceso a otro tipo de bases de datos y cosas por el estilo.

Aunque está documentado a nivel de API, con la suficiente información para que cualquiera lo pueda usar en un proyecto en Node, este es uno de los grandes problemas a los que nos enfrentamos en el desarrollo de software, sobre todo en proyectos más o menos complejos y grandes, y que se vuelve todavía peor cuando el diseño es deficiente y hay mucha deuda técnica acumulada; esto es, leer el código, por bien que esté estructurado y desarrollado, no te permite comprender la visión de conjunto de todo el proyecto con facilidad.

Para comprender bien un proyecto software, el código no es suficiente.

No estoy hablando de entender lo que hace una clase, o un método concreto dentro de ella, o incluso una librería de pequeño tamaño, sino de toda aquella información sobre la que se ha desarrollado el proyecto, con la que se han tomado decisiones y que no está reflejada claramente en el código, puesto que la forma y estructura de éste es consecuencia de lo primero.

Se podrá pensar que en el código está todo: clases, módulos, archivos de configuración; sin embargo, existe mucha más información que no está ni puede estar en él y que es imprescindible para comprenderlo por qué el proyecto se hizo de ese modo y para qué, más aún cuando llega el momento en que otros desarrolladores distintos de los originales lo tienen que asumir.

Esto, precisamente, ha sido algunas de las peores experiencias profesionales que recuerdo: haber tenido que retomar proyectos realizados por otros (que ya ni siquiera estaban en la organización para la que trabajaba). Recuerdo uno en concreto en java y otro en php, con miles de líneas de código y con varios años de desarrollo y evolución y con muchísima deuda técnica, y sin ningún tipo de documento de soporte: el código y punto.

Semanas de trabajo para comprender no solo lo que se había hecho por el momento, sino por qué, y sin posibilidad de preguntar a los autores, tan solo tú, el proyecto y mucha imaginación.

Retomar un trabajo hecho por otros suele ser en software una auténtica pesadilla que, en el mejor de los casos, puede llevar bastante tiempo, tan solo para comprender el proyecto suficientemente bien como para modificarlo y evolucionarlo.

Ahora bien, una vez que crees que lo has comprendido y puedes añadir cambios o hacer modificaciones, ¿de qué modo?, ¿con qué criterio en coherencia con lo que ya hay hecho?, ¿hay alguna razón desconocida por la que los antiguos desarrolladores hicieran algo concreto que tú habrías hecho de otro modo?

Lo que suele ocurrir es lo siguiente: llega un nuevo desarrollador que tiene que retomar un proyecto que no conoce y cuyos autores ya no están; se esfuerza en comprender lo que hay, cómo y por qué, pero, como digo, le falta mucha información y, si consigue echar a andar el proyecto finalmente, lo hará a su modo, seguramente añadiendo un nuevo estilo de diseño al anterior, modificando cosas sin saber por qué se hicieron de ese modo, modificando quizá el diseño original (o añadiendo uno nuevo), violando los criterios de la arquitectura (sin saberlo), aumentando así la falta de coherencia entre otros males.

Multiplica esto por varias manos diferentes y ya lo tenemos todo para un buen plato de código espagueti.

O sea, una situación bastante común en nuestro sector.

Me pregunto, ¿se puede evitar? Sobre todo, ¿se puede evitar sin necesidad de una documentación costosa y exhaustiva?

Para comprender bien un proyecto software, no solo es necesario que el código sea legible, con buena cobertura de pruebas, bien organizado, con clases o métodos sencillos, sin redundancias, limpio, sin deuda técnica, todas estas cosas que ya sabemos y de las que hablo mucho en mis libros, en concreto en El Libro Práctico del Programador Ágil.

Sobre todo en proyectos complejos y grandes, te pueden surgir preguntas del tipo siguiente:

  • ¿Cómo es la arquitectura del sistema?
  • ¿Qué criterio se ha usado para organizar los assets del proyecto? ¿Es coherente ese criterio en todo el proyecto?
  • ¿Cuál es la intención de diseño en esto y aquello?
  • ¿Cómo se crea un entorno de desarrollo y de testing?
  • ¿Qué flujo de trabajo es necesario para ejecutar todas las pruebas (si es que existen, claro)?
  • ¿Hay control de versiones? ¿Y cómo se sigue?
  • ¿Cómo se han resuelto ciertos requisitos no funcionales como la escalabilidad, restricciones, la seguridad, etc.?
  • ¿Dónde está localizada la configuración?
  • ¿Están las librerías actualizadas?
  • ¿Es compatible el proyecto con la actualización de las librerías de las que depende o hay alguna excepción?
  • ¿¡Por qué ese trozo de código está comentado!?
  • ¿Hay en algún sitio un diagrama de clases con su relación? Si lo hay, ¿estará actualizado?
  • ¿Por qué se usó esa librería en lugar de esa otra más popular? ¿Había alguna razón para ello?
  • ¿Qué criterios de usabilidad se siguió para la interfaz de usuario?
  • ¿Cómo se compila el proyecto o se pone en funcionamiento? ¿Qué dependencias hay?
  • Si el proyecto está dividido en capas o tiers, ¿dónde se localizan en el codebase?
  • ¿Cómo se escala el proyecto en un despliegue real?
  • Si existen bases de datos, ¿es su modelo suficiente para comprender su diseño?

Y un larguísimo etcétera. Si te fijas, muchas preguntas que para cualquier proyecto conocen bien los desarrolladores que trabajan en él desde el comienzo o desde hace mucho tiempo, pero para un recién llegado, esa información tan importante no existe salvo que alguien se la cuente. Claro, para el que lleva trabajando en ese proyecto un año, todo lo anterior es trivial, lo tiene todo en su cabeza a falta de documentación, sin darse cuenta de la cantidad de decisiones, asunciones y normas no escritas con las que se trabaja cada día... al margen de la misma naturaleza del código.

Esta dificultad suele aumentar cuando el proyecto lo han estado desarrollando las mismas personas durante años y no se han preocupado de simplificar y mucho menos de documentar nada, puesto que es tanto el conocimiento del mismo que tienen que no lo creen necesario, sin saber que esto precisamente puede ser un gran problema para quienes lo tengan que retomar en el futuro (y en ese futuro lejano, puede que sean ellos mismos quienes se encuentren la patata caliente después de haberlo olvidado casi todo).

Uno de mis mantras preferidos en software viene a decir algo así como que...

"Siempre tenemos que programar para que los demás comprendan lo que hemos hecho y por qué".

Pero añado algo más: no solo a nivel de código, sino también a nivel del proyecto en su globalidad.

Sin ir más lejos, recientemente he visto de primera mano la dificultad de asumir un proyecto de bajo nivel por personas nuevas en un equipo. Tanto es así y hasta tal punto puede llegar la dificultad, que en ocasiones es casi imposible asumirlo de modo que hasta se plantea la necesidad de volver a hacerlo desde cero, si es que la empresa se lo puede permitir, claro está.

Es cierto que el manifiesto ágil dice en uno de sus puntos: 

"Working software over comprehensive documentation (software que funciona sobre una documentación exhaustiva)"

Pero esto se ha interpretado mal: no quiere decir que no se documente absolutamente nada, sino que es más importante darle prioridad a que el software funciona que a crear documentación excesivamente exhaustiva, pero de ahí a documentación cero... Esto tenía mucho sentido en una época en donde esas metodologías pesadas te obligaban a presentar auténticos volúmenes con cientos de páginas con diagramas UML, etc. (que, por otra parte, nadie leía).

¿Hay entonces un camino intermedio entre no documentar nada y sobredocumentar?

¿Cómo documentar correctamente un proyecto software para que todo lo anterior no ocurra? Dicho de otro modo, ¿cómo se puede contar la historia completa sin caer en el error de documentar demasiado e innecesariamente y que no sea un coste excesivo en el proyecto?

 

Me encuentro a menudo con la siguiente situación: se desarrolla desde cero un nuevo proyecto, la funcionalidad a implementar está más o menos clara, se implementa, se entrega y... comienzan los problemas porque hay una gran cantidad de requisitos no funcionales que no se han tenido en cuenta (y que el cliente no ha indicado, claro está).

No solo estoy hablando de las necesidades de escalabilidad, rendimiento, mantenibilidad y todo eso que se denominan los conductores arquitecturales de cualquier producto software medianamente complejo. Desarrollar un nuevo proyecto implica también implementar todas las características necesarias para mantenerlo en producción, con funcionalidad específica para comprobar que todo está funcionando correctamente y con la trazabilidad necesaria para detectar dónde y cómo surgen los problemas. 

Todo lo anterior es necesario pero no suficiente.

¿Qué hay de toda esa funcionalidad al margen de la que el usuario final ve y usa? Me refiero a todo lo relacionado con la operación del sistema, algo de más relevancia aún cuando el proyecto es ciertamente complejo o tiene una gran cantidad de características.

Imagina una plataforma web como pueda ser Hub de Libros (el proyecto en el que más he trabajado en el último año): los usuarios se registran, los autores también, se pueden añadir reseñas y valoraciones de libros, los autores pueden indicar sus obras, crear su propia web de autor, los usuarios pueden seleccionar sus géneros preferidos, pueden escribir artículos, contratar servicios y pagarlos, crear estanterías con colecciones de libros y un larguísimo etcétera.

Toda esa funcionalidad, que es la que percibe un usuario que usa la plataforma, requiere de mucha más funcionalidad que éste no ve para operar el sistema. Esto es, hace falta una segunda aplicación totalmente independiente que permita actividades como: bloquear un usuario, restaurar su contraseña, aprobar valoraciones, comprobar los registros de log, gestionar todo lo relacionado con detalles internos de la plataforma (gestión de tareas, rendimiento de las bases de datos, etc.), obtención de métricas, gestionar características como "el autor del día", obtener todos los correos de los usuarios para crear una campaña de mailing, enviar un mensaje a un grupo de usuarios determinados, eliminar un libro que un autor ha publicado por error y muchas otras cosas por el estilo.

Cuando se publica un nuevo proyecto y muchas de esas actividades de operación se tienen que realizar tocando los registros de una base de datos, entonces es que no se ha planteado el desarrollo de la herramienta de operación necesaria.

Por resumirlo de algún modo: proyecto complejo = requisitos funcionales + herramientas de mantenimiento y operación.

El sistema va creciendo, en usuarios, en accesos y, afortunadamente, todo va bien y comienza su monetización: el cliente final (el dueño del proyecto) entonces requiere de cierto tipo de informes (¿cuántos usuarios hay?, ¿cuántos accesos al día?, etc.), sobre todo si se ha concebido el proyecto desde un punto de vista lean y hacen falta muchas métricas para decidir qué dirección darle con el tiempo según los resultados que se van obteniendo.

Más y más funcionalidad... de operación, claro.

Sin ir más lejos, en Hub de Libros se pueden contratar gigs para la ejecución de servicios de publicación (revisión, maquetación, creación de los archivos pdfs/epub de un nuevo libro, entre otros). Lógicamente, hace falta gestionar correctamente los gigs para que se realicen correctamente y que el usuario obtenga finalmente lo que ha contratado. Al usar Stripe para los pagos, hace falta comprobar también aspectos económicos como que las liquidaciones de esta pasarela son correctas, entre otras características tan solo relacionada con la contratación de los servicios.

Para ello, el sistema de operación debe implementar toda esa funcionalidad para su gestión: administrar la notificación de un nuevo gig contratado, comprobar su pago, enviarle mensajes asociados al gig para que el usuario los lea y muchas otras cuestiones que cualquier visitante de la web no ve, pero que está por detrás del funcionamiento de la plataforma y que además es imprescindible.

Una vez leí el comentario (en mi opinión algo tan cándido como ingenuo) de alguien que se preguntaba cómo es que Netflix tenía cientos de desarrolladores contratados puesto que la "web" o la aplicación no parecía demasiado compleja... en fin. Apuesto a que gran parte de todo ese equipo se dedica a implementar todo lo necesario para operar el sistema y dar soporte a necesidades del resto del negocio, algo mucho más allá de lo que el cliente final ve de la plataforma cuando se suscribe a ella y la usa.

En un sistema más o menos complejo, es difícil trasladarle al cliente toda esta funcionalidad en la que ni había pensado, más aún cuando las características y necesidades relacionadas con la opernación suelen ser mayores que las que se ofrecen a los usuarios finales.

La implementación de una aplicación de operación es necesaria y vital para el éxito de un proyecto, y no siempre se piensa en ella.

En concreto, en Hub de Libros existe un segundo portal de operación totalmente independiente y descoplado de el de usuarios (admin.hubdelibros.com) que permite realizar todo este tipo de operaciones y cuyo esfuerzo de desarrollo, lo puedo asegurar, ha sido mayor que el portal que ven los visitantes cuando acceden a la web.

Implementar toda esa funcionalidad de operación en segundas aplicaciones implica tener en cuenta muchos aspectos de seguridad, al tiempo que ese otro sistema (o conjunto de aplicaciones), tiene que tener acceso a los mismos repositorios que el sistema final, y, seguramente, a parte de la funcionalidad de los componentes que la constituyen. Y esto no es trivial, sobre todo si se quiere tener un sistema coherente sin que se provoque esa dispersión de aplicaciones implementadas de forma independiente, algo más costoso de mantener en el medio plazo.

Esta es una de las razones por las que implementé el framework de nombre Mantra (que, en estos momentos precisamente, estoy documentando para liberarlo en GitHub): un framework que tiene en cuenta desde su base, entre muchísimas otras características, que un mismo componente pueda implementar funcionalidad final y también de operación, sin romper la consistencia del sistema y facilitando su mantenimiento.

Recuerda: la funcionalidad de operación de un sistema es tan importante como los requisitos funcionales que el cliente exige.

 

Es cierto que estamos en la cultura de la prisa, en la que todo tiene que estar para antes de ayer, en la que los éxitos de otros se nos presentan como si hubiesen ocurrido de la noche a la mañana, generando la creencia de que nuestros objetivos más ambiciosos los podemos conseguir de una forma rápida.

Sin embargo, cuando analizamos el éxito aparentemente fulgurante de algún personaje de éxito, vemos que esa fachada mediática no es más que la punta minúscula de un iceberg que esconde en su base mucha perseverancia, fracasos, esfuerzo y tenacidad. Elon Musk, Bill Gates, Amacio Ortega, etc., por poner unos ejemplos extremos, todos comparten una historia parecida: muchas horas de trabajo, pequeños progresos y grandes resultados... después de años y hasta décadas.

Sin acaparar titulares, muchas otras personas alcanzan sus metas, que no necesariamente consisten únicamente en hacerse ricas: escribir un libro, perder peso, lanzar un proyecto emprendedor, caminar cada día, correr una maratón o plantar mil árboles.

Páginas

Mis libros en todas las tiendas:

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

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

 

Trabajo en...

Archivo

Mis novelas...