Puede que en la industria del desarrollo e ingeniería del software, algunos de los conceptos peor tratados (y peor entendidos), sean los de la arquitectura de un proyecto y el papel de un arquitecto software. En esos campos reina la confusión, las concepciones contrarias y una visión, me temo, poco práctica.

Es más, el mismo concepto de arquitectura software es dado a muchas interpretaciones (tantas como la misma evolución de cómo se afrontan proyectos durante las últimas décadas, me atrevería a decir), viniendo a crear aún más debate y falta de consenso claro la poca literatura que existe al respecto y que se centra más en patrones de arquitectura que en el papel real de un arquitecto dentro de una organización, cuando el trabajo de un reputado autor se contradice con el de otro igualmente alabado.

Para empeorarlo más, también se cree ingenuamente (formentado por la errónea cultura de muchas organizaciones), que ser arquitecto software supone un paso adelante en la escalera corporativa (más prestigio, mejor salario, etc.), de ahí el rechazo visceral de muchos desarrolladores a aceptar que venga alguien con un papel así cuando se entiende como una jerarquía tan pronto como perciben que su trabajo estará más o menos condicionado, definido y encorsetado desde la torre de marfil de un arquitecto.

Pero no tiene por qué ser así.

En El Libro Negro del Programador, dedico un capítulo ligero a este asunto sin profundizar (de título "El Mal Entendido Rol de Arquitecto de Software"), sin entrar demasiado en detalles, claro está, porque para mi mala suerte, una parte importante de mi experiencia con arquitectos ha sido más bien un desastre, y no lo digo con ánimo negativo o de devolver ningún agravio, cuando yo mismo he asumido ese papel en los últimos años en los productos que he dirigido y proyectos en los que he estado al frente.

Es un tema, digamos, delicado y controvertido, puesto que no existe una definición formal (te animo a que la busques, pronto te darás cuenta de que hay tantas como opiniones personales). Tanto es así, que en diferentes organizaciones nos podemos encontrar ese rol, pero con responsabilidades totalmente diferentes, cuando no ciertos equipos que se autodenominan ágiles creen que no hace falta cierta visión de arquitectura de los productos y proyectos que diseñan, o bien te encuentras al desarrollador al que han ascendido y por esa razón cree que sus decisiones van a ser mejores que la de sus antiguos compañeros de departamento (vamos, que se le ha subido el tema a la cabeza, quizá porque suena mejor decir que "eres arquitecto" a "soy programador").

Por otra parte, siento decir que se puede ser ágil, y al mismo tiempo, necesitar una arquitectura definida, y no es una contradicción (al menos en los términos que voy a indicar a continuación).

Para enredar más el asunto, antiguas prácticas sobre cómo a afrontaba el desarrollo de software hace unas décadas, siguen persistiendo en el inconsciente colectivo de los denominados arquitectos, me temo. Para muchos, todo lo que habla de arquitectura tiene que estar relacionado con diagramas UML tan espesos como inútiles que poco aclaran y estructuras en las que necesariamente todo el desarrollo debe encajar necesariamente (tan solo recuerdos de dinosaurio sobre cómo se afrontaba el desarrollo de software hace mucho tiempo pero que aún perduran), siendo más un obstáculo que un inconveniente. En otros equipos (lo digo porque me los he cruzado en algún momento de mi carrera profesional), sencillamente ignoran que exista tan siquiera ese concepto: el software de desarrolla de forma monolítica y se despliega como sea y punto (puff...), cuando no se confunde el diseño con la arquitectura, algo también muy habitual.

Puede que precisamente por todo lo anterior, no haya escrito hasta ahora demasiado sobre esto (ni me haya mojado en el asunto, para ser sincero), por suponer un concepto muy dado a la malinterpretación e incluso susceptible de acumular poder en ciertos entornos corporativos; no obstante, voy a hacer a continuación algunas aclaraciones que confío que ayuden un poco a tener una idea más clara de lo que para mí es un arquitecto software y que, afortunadamente, he visto confirmados en autores seguramente con más experiencia que yo (como Simon Brown y George Fairbanks).

El arquitecto software no es un puesto, sino un rol.

Llevo muchos años diriendo equipos de desarrollo, y siempre les digo lo mismo a mis compañeros: no soy el jefe de nadie, tan solo tengo el rol que me corresponde y mi trabajo consiste en ayudar a que el suyo lo hagan lo mejor posible. Del mismo modo, un arquitecto software no se puede parapetar tras un cargo, sino que asume un rol activo con determinadas funciones y responsabilidades. Tanto es así, que no es mejor profesional por tener ese rol que un desarrollador. Otra cosa es cómo se valore dentro de una compañía, pero en mi opinión lo único cuantificable económicamente debe ser la experiencia y el valor de lo que se aporta.

Un buen arquitecto no vive en su torre de marfil, sino que también programa.

El desarrollo de software no es como otras profesiones; no podemos seguir el símil de arquitecto de edificios / aparejador / albañil, etc., puesto que un arquitecto puede no haber tocado un ladrillo en su vida. No obstante, en software, un arquitecto debe haber desarrollado mucho software a lo largo de su carrera, y, además, en cuantos más proyectos diferentes se haya involucrado, mejor aún.

Es más, abandonar tu papel como desarrollador y dedicarse solo a la arquitectura, lo hace alejarse seguramente de ahí donde es bueno, de modo que para mí un buen arquitecto debe seguir implicado necesariamente a nivel de código en el proyecto.

El arquitecto conoce perfectamente el dominio.

El arquitecto debe conocer perfectamente lo que el cliente necesita o el universo del negocio que se va a modelar con el sistema que se pretende construir, ¿de qué modo si no se van a tomar las decisiones de arquitectura más relevantes?

Gestión de riesgos: no siempre hace falta una arquitectura.

La regla es sencilla: cuanto más grande va a ser un proyecto software y más largo su ciclo de vida (años), más necesario es la perspectiva de la arquitectura que se va a seguir.

Un proyecto pequeño no necesita el papel de un arquitecto.

Esto es, hay una relación directa entre la gestión del riesgo, tamaño del proyecto y su proyección a largo plazo.

Se confunde arquitectura de despliegue IT con la arquitectura de un producto/proyecto.

En ciertos entornos, he visto cómo se confundía una cosa con la otra. La arquitectura de un sistema software no es lo mismo que la arquitectura IT de despliegue final del sistema a desarrollar, pero están relacionados, obviamente. Si sabemos que el despliegue se va a realizar en una infraestructura IT cloud, o bien en un único servidor, la arquitectura propuesta puede cambiar.

Una mala arquitectura (o ausencia de ella) puede costar mucho dinero.

Lo he visto: un sistema que tenía que evolucionar pero cuyos desarrolladores trabajaban sin ese horizonte temporal y orden que pudiese proveer una arquitectura correcta para ese proyecto. El resultado era que esa falta de perspectiva (o inexperiencia) más muchos déficits de diseño, se cubría con muchos euros en hardware.

No hay conflicto entre lo ágil y definir una arquitectura al comienzo.

Así es, léelo de nuevo por si esta afirmación a estas alturas te choca. Como siempre me digo a mí mismo, la virtud está en el término medio.

Por alguna razón, quizá por el abuso en tiempos pasados de todo lo que huela a arquitectura, a los equipos que defienden lo ágil dogmáticamente, les parece una aberración plantearla, creyendo erróneamente que ésta emergerá. No se comprende que lo que emerge es, en el mejor caso, el diseño, y que la arquitectura va mucho más allá que definir cajas, trazar líneas e interacciones entre partes funcionales del proyecto, como veremos más adelante.

Algunos puntos del movimiento ágil se han malinterpretado, me temo; desde un punto de vista del concepto de arquitectura como visión y estructura de un sistema software, lo que emerge es el diseño de los componentes o piezas de software que lo componen, no ese marco más general. De nuevo, se pierde la perspectiva cuando uno cree que un proyecto de 10 KLOCs se debe gestionar y debe crecer igual que uno de 100 KLOCs.

La arquitectura consiste también en identificar riesgos.

Un arquitecto guía, documenta, propone, ayuda al resto del equipo, etc., pero también es capaz de identificar los riesgos que pueden presentar ciertas decisiones (elección de tecnología, licencias de terceros, puntos únicos de fallo, etc.).

No es imprescindible UML para documentar una arquitectura.

Nueva sesión en directo para GeeksHubs en su canal de YouTube. En esta ocasión, basado en uno de mis libros (The Coder Habits), hablé sobre los hábitos que un desarrollador de software debe incluir para mejorar su carrera profesional: hablamos sobre soft-skills, la regla 50/50, evitar el happy path, sobre cómo trabajar concentrado y muchos otros temas que mí me parecen muy esenciales para trabajar mejor, con menos esfuerzo, siendo más productivos y generando un código de más calidad.

Puedes ver la sesión aquí aunque lo tienes embebido un poco más abajo.

Ya sabes: si te sientes atascado en un carrera como programador, quizá lo que te falta es incorporar mejores hábitos.

Gracias al equipo de GeeksHubs por invitarme a esta nueva sesión.

Este es uno de los aspectos que menos me gustan de las diferentes actividades que están dentro de mis responsabilidades.

Estimar el esfuerzo que hace falta para generar un proyecto es un arte en sí mismo, y en software, me atrevería a decir que peor aún. A continuación voy a enumerar algunas de las razones e incertidumbres por las que yo prefiero trabajar en proyectos a muy largo plazo (que van a durar posiblemente años) o productos que, en cualquier caso, tienen un ciclo de vida más largo.

En esta otra entrada, hace un tiempo comenté las ventajas e inconvenientes de trabajar en productos o proyectos, entendiendo por proyectos aquellos encargos que comienzan en una fecha, terminan en otra y se cotizan con un presupuesto cerrado.

De entre mis responsabilidades, forma parte la necesidad de estimar las horas que hacen falta para desarrollar un nuevo proyecto comenzado desde cero o bien crear un nuevo evolutivo para uno ya en producción; en más ocasiones de las que me gustaría, te encuentras en la situación de necesitar una bola de cristal para acertar lo mejor posible ya que el cliente espera que puedas fijar el trabajo que te quiere encargar a un precio fijo y tú lo único que puedes estimar es aproximadamente las horas necesarias para su realización: si aciertas, perfecto, si cotizas menos horas de las finalmente necesarias, entonces se pierde dinero en el proyecto o baja su rentabilidad, si se acaba en menos horas de las utilizadas finalmente, ésta aumenta.

Suelo comentar con mis compañeros desarrolladores que llevarán el peso del trabajo su opinión al respecto, para así tener más información que contrastar.

Sé que existen técnicas de estimación que, en cualquier caso, tratan de minimizar el peor escenario posible: que se tarde mucho más tiempo del esperado en finalizar un proyecto, incurriendo así en costes extras no cotizados para el cliente y desviaciones económicas (esto es, que se pierde dinero, vaya).

No se trata de la experiencia que tengas desarrollando proyectos o dirigiéndolos, aún conociendo muy bien la tecnología a usar o el universo del negocio relacionado con los mismos e incluso conociendo con detalle las capacidades de los desarrolladores que estarán más implicados en el trabajo.

Inevitablemente, siempre hay ciertas incertidumbres que escapan a tu control y aspectos contra los que poco puedes hacer: el cliente no tiene claro ciertas funcionalidades de lo que necesita desarrollar (los va definiendo a medida que comienza a ver algo en marcha, algo también comprensible), el cliente no quiere esforzarse demasiado en consensuar un documento de especificación (y tú, puesto que quieres que te encargue el proyecto, tampoco eres demasiado pesado para afinar los detalles al máximo, o sea, que te ves un poco entre la espada y la pared), como el que compra una caja de material de cualquier tipo, el cliente quiere un precio cerrado y un tiempo de desarrollo, salvo que tengas mucha disciplina y una mano muy amable para conseguirlo, intentas minimizar las reuniones al máximo (en donde se van muchas horas), si en el mismo proyecto existen dependencias de terceros, éstas van a condicionar también el esfuerzo necesario, aunque al principio, cuando estás cotizando, no tienes ni idea de cuánto.

En pocas palabras, incertidumbre + incertidumbre + incertidumbre...

Esto es, muchas veces, vas en cierta medida a ciegas, lo que no deja de ser un contrasentido cuando el cliente quiere un precio cerrado y tú manejas una incertidumbre de más menos el 30% en el tiempo (por decir algo).

O peor aún, y algo típico en compañías grandes: esa estimación no la ha realizado nadie relacionado con el equipo técnico, sino alguien de otro departamento sin experiencia suficiente.

Y todo puede emperoar aún más porque para el cliente no eres el único proveedor candidato: mi experiencia me muestra (y ojalá que no sea la misma para todo el mundo), que en última instancia, variables como el compromiso, confianza y calidad, se supeditan irremediablemente al coste final, o lo que es lo mismo, te eligen por el precio/hora como única variable de selección.

Ya sabemos que la productividad de los desarrolladores depende de muchos factores, no únicamente del talento o experiencia que tenga cada uno. Sobre todo en pequeñas compañías, es habitual que un mismo desarrollador tenga que hacer frente al mismo tiempo a más de un proyecto o el día menos pensado hay que apagar algún fuego, añadiendo así una pérdida de tiempo al cambiar de contextos y terminar tareas de un proyecto u otro diferente (tiempo imposible de estimar).

Por otra parte, también sientes la presión añadida de que el cliente quede con un grado alto de satisfacción para que así recurra a ti o tu compañía en otra ocasión, algo en ocasiones difícil de gestionar con clientes difíciles.

Por si no te habías dado cuenta hasta ahora, existen clientes buenos malos (y no siempre los puedes elegir, me temo): los primeros se ajustan más a lo especificado y se esfuerzan mucho para permitir que tú trabajes lo mejor posible porque te ven parte de su equipo (están comprometidos con el proyecto), los segundos esperan que les leas la mente y se toman el derecho de cambiar especificaciones en cualquier momento haciendo que el equipo pierda horas al modificar lo ya realizado (tiempo no cotizado) o no comprenden que cuando se entrega un proyecto, tu parte termina ahí a no ser que exista un acuerdo para el mantenimiento del mismo. Estos últimos tan solo están implicados en el proyecto, y tú, como responsable del mismo, tienes que actuar en ocasiones como paraguas para evitar que el cliente cambie demasiadas cosas en reuniones con cierta tensión.

Es posible que te identifiques claramente con el escenario anterior: te piden que cotices y construyas un edificio pero no te dicen cuántas plantas se tiene, el tamaño de las ventanas te lo dicen después y ya veremos si lleva garage o no, y eso sí, la fecha de entrega es inamovible.

Siento si te estás agobiando al leer hasta aquí, pero todo lo anterior forma parte de la dinámica muy común de muchas compañías cuyo modelo de negocio consisten únicamente en contratar proyectos, a precio cerrado, con fecha de inicio y de fin, y que al tratar de manejar toda la incertidumbre anterior, al final de la cadena, se tiene a desarrolladores estresados, haciendo rápido lo que requiere de mucho más tiempo de dedicación y haciendo que las cosas en producción no se caigan en cualquier momento.

Es cierto que siempre existe cierta indeterminación cuando se especifica, de ahí que el enfoque ágil sea una herramienta maravillosa para reducir esa incertidumbre, pero la cuestión es que casi siempre, terminas infracotizando el esfuerzo real por uno u otro motivo.

Por muy bien que apliques las buenas prácticas de diseño, preparando tu proyecto software para el cambio, con una buena arquitectura y una calidad de código excelente, no se va a poder amortiguar toda esa incertidumbre fácilmente.

Siendo así las cosas, se explica perfectamente que en ocasiones se entreguen proyectos con un diseño deficiente y mucha deuda técnica, por falta del tiempo necesario para hacer iteraciones de mejora o exigencias de tiempo del cliente imposibles de abordar. Sencillamente, a veces es imposible cuadrar el círculo.

No siempre se tiene el margen suficiente para elegir los proyectos que tienes que desarrollar o dirigir, puesto que el negocio manda y hay que rentabilizarlo para pagar gastos, nóminas, etc.

Por todo esto, cuando me encuentro algún proyecto con graves deficiencias, nunca apunto a los desarrolladores que lo hayan realizado, sino más bien a las condiciones en las que lo han hecho. Y, sorpresa, casi siempre hay detrás una dinámica de trabajo en la que todo tiene que estar para antes de ayer, sueldos reducidos o proyectos infracotizados y mal especificados.

Para evitar el máximo esta dinámica desagradable, yo siempre trato de identificar a la persona coordinadora por parte del cliente y lo implico al máximo para que valide lo que se avanza en iteraciones pequeñas (de una a dos semanas), pero la experiencia también me muestra que los proyectos se cogen al principio con muchas ganas y poco a poco, ese esfuerzo recurrente de validación, ese coordinador termina viéndolo como una tarea pesada más (porque tiene otras que atender de su propia organización, claro).

¿Cuál es tu papel entonces como director de proyectos como es mi caso?

A mí no me cabe la menor duda: no soy ni el jefe y no me gustan las jerarquías ni tampoco me gusta ordenar como un general que manda a los soldados como carne de cañón. Yo tengo claro que mi papel asume toda la responsabilidad en el buen desarrollo del proyecto y su entrega con la suficiente calidad y que mi principal misión es favorecer las condiciones en las que los desarrolladores trabajan, lo que también implica que el cliente haga su papel (en ocasiones no es sencillo).

Como ya sabemos, un trabajo creativo requiere de ciertas condiciones para su realización, y éstas es responsabilidad de todos los miembros de una compañía para conseguirlas, también del cliente.

¿Y entonces? ¿Es posible escapar de la dinámica anterior de trabajar en proyectos infracotizados la mayoría de las veces (igual a presión)? ¿Cómo asegurar entonces la rentabilidad de cada proyecto?

En este primer post del año, quiero reflexionar acerca de una característica que llevo observando en los proyectos que implemento o dirijo desde hace más tiempo del que recuerdo, pero que quizá no se tenga demasiado en cuenta cuando estamos desarrollando software.

Si has tenido alguna vez la sensación de que se han implementado funcionalidades o características similares de un proyecto a otro, entonces puede que tengas la oportunidad de extraerlas de un modo útil para su reutilización. No en vano, no tiene sentido implementar un nuevo proyecto totalmente desde cero (sin usar ningún tipo de framework y librerías de terceros), reinventando la rueda una y otra vez, a no ser que se esté experimentando o aprendiendo.

Aunque pueda sonar algo extraño, el denostado y fatídico 2020 ha sido para mí un año muy productivo y creativo; al margen de todo lo relacionado con estos tiempos agitados que estamos viviendo con pandemia, confinamientos, derrumbe económico, etc., puedo decir que, afortunadamente, lancé varios proyectos que espero que vayan mejorando en los próximos meses; algunos de ellos se venían gestando desde el año anterior, otros, como mis libros y que también considero proyectos, fueron surgiendo a medida que acumulaba temas sobre los que hablar y que pudiese sintetizar en ese formato, sobre todo después de lanzar Hub de Libros.

Siempre he animado a todo el mundo a estar trabajando en proyectos personales y no solo dedicarse exclusivamente a aquellos por los que les pagan como empleados en sus compañías o los que te contratan como freelance: la riqueza que se obtiene de dedicar tiempo a ellos siempre me ha parecido que es incluso superior a la de realizar cursos, seminarios y leer libros.

Tanto es así, que, con el tiempo, comienza a diluirse la frontera de lo que es un proyecto personal y lo que no, ya que yo, a estas alturas, lo considero parte de mi trabajo profesional y me tomo tan en serio tanto lo uno como lo otro, independientemente de mi condición de freelance y consultor independiente. Es más, proyectos que inicialmente eran personales y realizados casi por juguetear un poco, terminaron convirtiéndose en productos comerciales y corporativos, como Picly.io.

En mi propio cocktail de autoformación continua, siempre tengo uno o dos libros que estoy leyendo (tanto técnicos como de muchos otros temas), podcasts que escucho regularmente y algún que otro curso, cuando no aplico ese principio que dice que aprendes lo que enseñas, de ahí que regularmente trabaje en un nuevo proyecto literario, y este nuevo año tengo ya varios proyectos en mente. Y, sin embargo, y como decía antes, lo que percibo como más enriquecedor es realizar un proyecto de verdad, porque, lógicamente, se aprende leyendo, escuchando podcasts y haciendo cursos, claro está, pero lo que has aprendido solo se consolida en conocimiento cuando lo has puesto en práctica. Obvio.

Leer esta bien y es necesario, qué duda cabe, pero aplicar lo aprendido es todavía mejor.

Sin embargo, hay una característica de realizar proyectos (tanto dentro de una empresa como personales) que me viene a animar todavía más para realizarlos y que requiere de trabajar con cierta actitud porque afecta incluso al modo en que los enfocas y diseñas.

En software, la reutilización es un concepto fundamental: nada peor que encontrar redundancias dentro de la misma solución. Eliminarlas es importante para mantenerla un poco más limpia y mejor estructurada; tanto es así, que en la metodología (una de tantas) que propongo para modernizar proyectos heredados en mi último libro (Legacy Code: Cómo modernizar en catorce pasos código heredado o proyectos software que han crecido demasiado rápido), le dedico un capítulo completo.

Hay diferentes niveles en esta reutilización de la que hablamos: puede afectar a simples funciones, clases de ayuda o componentes, pero también a grupos funcionales de mayor importancia dentro del proyecto.

Un paso más allá consiste en tener cierto nivel de abstracción y ver, concretar y diseñar dentro del mismo proyecto, otros de menor tamaño en los que se apoya.

En Hub de Libros, sin ir más lejos, se utiliza un potente gestor masivo de archivos que, poco a poco, fui extrayendo como un proyecto propio y que lo tengo publicado con el nombre de files-repo en GitHub; del mismo modo, el framework en el que se basa (Mantra), fue generando poco a poco una librería a modo de ORM que, también, extraje como proyecto independiente (se trata de RedEntities), y algunos más que aún no he publicado.

De este modo, un mismo proyecto ha generado diversos subproyectos independientes que, sin duda, reutilizaré a menudo y que quién sabe a dónde me conducirán.

La dificultad de extraer un subproyecto no radica en copiar y pegar sencillamente un conjunto de clases o componentes, sino en implementarlo de modo que no esté vinculado al proyecto padre de donde surgieron para así aportar una solución que se pueda integrar con naturalidad y no forzadamente en otros proyectos.

Con el tiempo, mantener esta actitud de detectar lo que puede ser un nuevo subproyecto, tiene ventajas inesperadas, ya que de ese modo, cuando te enfrentas a un nuevo desarrollo y que, como yo, tienes la responsabilidad de estimar el esfuerzo y hasta de determinar las bases de su diseño y arquitectura, piensas y lo enfocas ya no solo como un conjunto de componentes que se orquestarán de algún modo, sino que los abordas también con un conjunto de subproyectos que se desarrollarán independientemente y que serán integrados a su debido tiempo.

De este modo, animo a trabajar con esto en mente y a detectar qué partes homogéneas de una solución se pueden extraer como proyectos independientes.

Esto, además, puede ser hasta una estrategia comercial para obtener más productos de lo desarrollado en uno de ellos, algo que también he hecho en los últimos años tratando de rentabilizar librerías y desarrollos que se hicieron específicamente para ciertos clientes.

Conclusión: si pensamos en un nuevo desarrollo tratando de distinguir algunos subproyectos que se integran en él, lo podremos rentabilizar mejor y la reutilización de éstos nos permitirá avanzar más rápido en los siguientes proyectos y hasta plantear nuevos productos independientes.

Recientemente me invitaron en GeeksHubs para dar alguna charla sobre los contenidos que suelo tratar en mis libros.

El pasado diez de diciembre tuve la maravillosa experiencia de hablar en una sesión de una hora de un tema que me gusta mucho; lo titulamos "Introducción a las bad smells y diez estrategias para mejorar código heredado", aprovechando la publicación hace también muy poco de mi último libro ("Legacy Code: Cómo modernizar en catorce pasos código heredado o proyectos software que han crecido demasiado rápido") y que, parece ser, está despertando mucho interés, lo que me indica que el escenario de mejorar código heredado es más frecuente de lo que pensaba.

Os dejo el enlace del video en YouTube aunque lo muestro aquí embebido también:

Toda una experiencia hablar en directo delante de tantas personas.

Agradezco desde aquí al trabajo de Manu y Verónica de GeeksHubs para permitirme hablar sobre deuda técnica y hacer una introducción a las bad smells.

 

No lo olvides: tu enemigo número uno como desarrollador de software, es la deuda técnica.

Si llevas poco tiempo programando, enhorabuena, lo que vas a leer a continuación puede que te ahorre miles de horas de trabajo y tu carrera profesional sea mejor a lo largo del tiempo.

Algo que siempre me gustó de la programación, es que el desarrollo de software presenta aspectos sutiles que son difíciles de comprender en un principio hasta que lo experimentas por ti mismo.

Quizá un buen método de aprendizaje consista en caer en todos los errores posibles y después darte cuenta de su solución, aunque lamentablemente eso, en el contexto de una compañía, supone pérdida de ingresos, proyectos fracasados y seguramente tu búsqueda de un nuevo empleo.

Con el tiempo y la experiencia, vas acumulando cierta sabiduría de modo que ya sabes con antelación las consecuencias a largo plazo de hacer algo de un modo u otro.

Imagina qué ocurriría si durante un mes, nadie se preocupa de recoger, ordenar y limpiar la cocina de tu casa. El primer día no pasaría nada, el segundo, quizá, es ya algo molesto prepararte un simple sandwich, pero desde luego, después de una semana, la cocina será un espacio sucio e intransitable. Sigue siendo una cocina, pero hacer algo en ella costaría cada vez más trabajo (aparte de lo asqueroso, claro).

Pues bien, muchas veces dejamos que nuestro proyecto crezca de ese modo (o nos vemos obligados en una dinámica de trabajo irregular, para «antes de ayer» y en medio de una gran desorganización), casi sin darnos cuenta vamos dejando poco a poco piedras en el camino que se convertirán en rocas hasta que no podamos transitar más por él.

Una mente ingenua e inexperta, podría pensar: si ya esto funciona, ¿para qué me voy a molestar?, ignorando que «sobre lo que ya funciona» habrá que incluir más funcionalidad o modificar la existente.

La deuda técnica se produce de un error muy frecuente entre los programadores, sobre todo los noveles: programar no consiste únicamente en escribir líneas de código y ya está.

Sí, vuelve a leer lo anterior una vez más.

¿De qué hablo cuando hablo de programar?

Rara vez ocurre que lo que haces a la primera es algo perfecto que no necesita ser tocado nunca más, menos aún en el contexto de un proyecto que crece casi siempre con requisitos que ni imaginas aún.

Esto es, hay que programar para que las líneas de código que escribes puedan ser modificadas más adelante.

Ese acto de «modificación», sea para lo que sea, también es programar.

¿Funciona lo que has hecho? Puede que sí, pero ¿cómo te aseguras de que siga funcionando más adelante cuando el proyecto crezca? Creando pruebas, claro. Programar también consiste en desarrollar una batería de tests que cubran la mayor parte de tu código.

¿Tiene tu proyecto el mejor diseño posible? Salvo que seas un desarrollador muy experimentado, lo normal es que inicialmente el diseño ni se te pase por la cabeza, tan solo añades funcionalidad del modo que sea y ya está, más aún cuando las fechas aprietan y quieres volver a casa pronto (caso típico en donde surgen archivos de cientos de líneas de código = ausencia de diseño).

Sin embargo, sin diseño, tu aplicación es como el edificio cuyos cimientos, vigas y columnas fuesen de arcilla.

El diseño es la estructura de la aplicación que te permite añadir funcionalidad y mantenerla de una forma ordenada y eficaz (en el menor tiempo posible). Un diseño de calidad, viene a ser como un plano o guía que permite comprender la aplicación mejor.

Diseñar, o mejorar el diseño existente, es también programar.

A medida que una aplicación crece, la vamos complicando, necesariamente, de ahí que «simplificar» sea esencial para que ese crecimiento sea ordenado. ¿Simplificar qué? Nombres de función, algoritmos, extraer funcionalidad común, hacer más legible ese bucle, etc. No es suficiente que tú comprendas el código, lo tienes que hacer de modo que cualquier otra persona lo pueda entender con el menor esfuerzo posible.

Hay que programar para que otros asuman lo que haces con facilidad.

Todo eso debe formar parte de nuestro tiempo «programando». Demasiadas veces he visto aplicaciones en donde la lógica de negocio está en su totalidad en una única clase de miles de líneas con un estilo de programación que difícilmente lo va a comprender otro que no sea su autor.

No respetar todo lo anterior, y consideraciones similares, supone añadir las piedras en el camino de las que hablábamos antes: esas piedras son las deudas que se van acumulando de forma inevitable hasta que tú mismo te vas dando cuenta de que añadir más funcionalidad, modificar la existente o depurar un error, es cada vez más difícil, cuando no imposible.

Tu trabajo como programador consiste en reducir la deuda técnica al máximo. Ésta es inevitable que se produzca porque es consustancial al desarrollo de software (otra frase que quizá debas leer de nuevo).

Es más, afirmo que parte del ciclo de desarrollo de una aplicación debe consistir en detectarla y mejorar cualquier aspecto del proyecto. Sorprendentemente, esa actividad creativa de mejora tarda menos de lo que pensamos y es muy gratificante, al menos lo es para mí.

Esas mejoras pueden ser micromejoras que, a lo kaizen, con el tiempo van produciendo grandes cambios positivos en la aplicación.

(Extracto de uno de los capítulos del libro "Legacy Code: Cómo modernizar en catorce pasos código heredado o proyectos software que han crecido demasiado rápido", disponible a partir del 5 de diciembre en todas las plataformas).

Legacy Code

 

Las Doce Claves: Doce Habilidades y Estrategias para Emprender con Éxito

Este es mi primer trabajo para un público general, no necesariamente técnico, interesado en todo lo relacionado con el emprendimiento, en donde describo las doce habilidades y estrategias que a mí me han resultado más útiles cada vez que he puesto en marcha un nuevo proyecto o he tenido un nuevo propósito que felizmente he terminado con éxito.

Curiosamente, de mi anterior libro, “El Arte del Emprendedor Digital”, he recibido un feedback inesperado. La mitad de su contenido trata de los aspectos más técnicos que he puesto en marcha al implementar Hub de Libros, el resto, son capítulos de desarrollo personal y de estrategias de emprendimiento: prácticamente ha sido una constante los comentarios en que me indicaban que de ese otro libro, los capítulos de este último tipo habían gustado tanto o más que los estrictamente técnicos, algo que, por otra parte, no me sorprende en absoluto puesto que lo profesional difícilmente irá a mejor si no se dominan ciertas habilidades personales.

De modo que en “Las Doce Claves”, he extraído todos esos capítulos, los he revisado a conciencia exhaustivamente y los he adaptado a un público más general, quitando todo aquello que sonara excesivamente técnico.

¿El resultado? Mi primer libro de desarrollo personal útil para cualquier persona que abrace el emprendimiento como modo de vida o que sencillamamente esté pensando en lanzar nuevos proyectos.

Sin duda, existen muchas otras claves para crear un proyecto de éxito, y qué duda cabe también de que existen autores mucho más reputados que yo y que considero mis propios mentores y que recomiendo encarecidamente (como Raimon Samsó, Sergio Fernández, Tony Robins, Brian Tracy, y muchísimos otros).

No obstante, en “Las Doce Claves” se encuentra lo que yo he valorado más a la hora de poner en marcha proyectos como Hub de Libros y otros con anterioridad, después de mucho tiempo analizando cuáles eran esos atributos, virtudes y actitudes más importantes para avanzar en ellos, o al menos los que a mí me han resultado más útiles.

¿Y cuáles son esas claves?

En el juego del emprendimiento predominan ciertas habilidades personales, pero también otras de tipo organizativo, más aún en personas que, como yo, tenemos muchas otras responsabilidades profesionales y familiares (como la mayoría de la gente).

En cierto modo, se puede decir, que quienes emprendemos fuera de nuestros trabajos oficiales, tenemos algo así como un doble trabajo, de ahí que la optimización del tiempo y la productividad sean esenciales.

Si al cocktail le añadimos que queremos poner en marcha un proyecto ciertamente complejo que nos llevará bastante tiempo y dedicación, entonces es necesario avanzar en él con una planificación basada en tareas. Es más, en microtareas, que, bien definidas y de corta duración (preferiblemente menos de una hora), hará que puedas avanzar en tu proyecto cada día. Piénsalo, tres o cinco microtareas al día, durante una semana, un mes, varios meses, son muchas tareas completadas que necesariamente te acercarán al final de tu proyecto.

Divide tu proyecto, o cada semana que trabajas en él, en pequeñas tareas muy concretas, utiliza una herramienta tipo to-do y ve completándolas a tu ritmo, pero con constancia.

Pronto descubrirás el placer que supone ir eliminándolas de la lista.

Hub de Libros es una realidad después de un año de haber completado quizá varios miles de microtareas, pero de forma constante y lo mejor organizadas posible.

Avanzar así, forma parte de una cultura de trabajo basada en kaizen, esto es, de una fisolofía de vida en la que mejoramos constantemente pero a muy pequeños pasos. Lo importante no es la velocidad, ni la cantidad, sino el saber que todo es revisable y susceptible de mejora, y, como resultado, con el tiempo, se produce un efecto bola de nieve sorprendente.

Yo he integrado kaizen a muchos aspectos de mi vida, desde mi cuidado físico hasta la forma de enfocar mi trabajo profesional, y tan solo me digo a mí mismo que ojalá este concepto lo hubiese conocido mucho antes.

Kaizen es uno de esos conceptos que engloban una riqueza increíble, como ikigai y otros parecidos de la cultura japonesa, demasiado para exporner todos sus detalles y matices en un simple artículo. Tan solo animo a indagar más en él y a incorporar kaizen en tu día a día.

Por otra parte, dejamos que se apoderen de lo más importante que tenemos en nuestra vida: nuestra atención y nuestro tiempo.

Continuas llamadas, interrupciones, notificaciones de las aplicaciones de nuestro smartphone, reuniones dispersas, improvisadas e interminables, etc. Todo ello hace que no podamos trabajar apenas concentrados. Sin embargo, para llegar al fondo de una tarea y para realizarla sin estrés y lo mejor posible, hace falta trabajar la mayor parte del tiempo concentrado. Sencillo, evidente, pero no fácil de conseguir en un día a día que parece que cada vez está más lleno.

Y yo me pregunto, ¿lleno de qué?

Seguramente si analizamos en qué se nos van las horas del día y los días de la semana, lleguemos a una conclusión sorprendente: pasamos demasiado tiempo haciendo tareas improductivas, sobre todo si somos personas acostumbradas a ser incapaces de decir no a todo lo que los demás nos exigen.

De ahí que en Las Doce Claves, simplificar nuestro día a día, nuestra vida en general, vaya, y tratar de trabajar lo más concentrados en nuestras propias islas de concentración, es imprescindible.

Pero emprender un proyecto, sobre todo si se espera de él algún resultado económico en un mercado incierto, voluble e impredecible, no se puede dejar al azar, necesitas un método, pero no un sesudo y pesado documento de modelo de negocio de quinientas páginas, sino algo ágil, práctico y que cualquiera puede poner en marcha.

Tu proyecto no es un proyecto en realidad, sino una hipótesis que tienes que validar.

¿Quién la valida? Los usuarios, claro.

¿Cómo lo validas? Con datos, por supuesto.

De ahí en Las Doce Claves haya un capítulo especial a la metodología Lean, propuesta inicialmente por Eric Ries en su libro ya clásico y de título “El Método Lean Startup: Cómo Crear Empresas de Éxito Utilizando la Innovación Continua”, y que dio lugar a una auténtica cultura lean tan productiva como útil.

Que el título del libro de Eric Ries no te asuste, es útil y ameno para cualquier persona con o sin experiencia y que quiera conocer cómo avanzar en un proyecto dirigiéndolo hacia más y mejores resultados mediante pequeñas pero frecuentes iteraciones de trabajo: crear / lanzar / medir / iterar. Así, hasta que, poco a poco, los resultados se van dejando ver.

Como comento en Las Doce Claves, tu proyecto emprendedor es un barco a la deriva en un mar enorme e impredecible: tu trabajo consiste en dirigir el rumbo para llegar al puerto al que te interesa arribar.

¿Cómo? Con datos medibles, con qué si no.

De la mano de lean, hay un capítulo dedicado a la importancia de la recopilación de analíticas, esto es, los datos realmente importantes que necesitas conocer de tu proyecto para evaluar su tendencia y éxito. Me gusta afirmar que en este capítulo desmitifico totalmente todo lo relacionado con la adquisición de datos de tu proyecto en marcha, es tan sencillo como trivial, porque lo importante no es obtener esos datos, sino que sepas que sin ellos, te encuentras ciego ante lo que está ocurriendo. Es como llevar a cabo una dieta y salir a correr tres días en semana y no subirte a la báscula en ningún momento. La analítica consiste en analizar esos datos, sacar conclusiones y tomar decisiones al respecto.

Red Entities

Un artículo de Rafa G. Blanes

He publicado en GitHub un nuevo repositorio de una librería extraída de todo mi trabajo realizado por el momento en Hub de Libros.

Se trata de Red Entities, un object mapper y query builder con el que hacer transparente el acceso a las entidades de datos con algunas particularidades que me animaron hace un año a construirlo y no usar otro tipo de proyectos similares. De momento, es compatible con varios sabores de Mysql y Sqlite y probado con Node.js 10, 12, 13 y 14.

Red Entities

Aunque he utilizado mucho GitHub y tengo publicados varios repositorios, con Red Entities he trabajado mucho en la documentación y en el ciclo de vida para publicar un proyecto así y que esté disponible también como paquete en NPM.

Tal y como comento en la documentación, hay una intención de diseño detrás de Red Entities, relacionada con la concepción de proyectos altamente escalables, esto es, proyectos que van a crecer mucho en todos los sentidos y que, además, no tenemos ni idea de hacia dónde se van a dirigir.

En software hay un principio que no siempre tenemos en cuenta: proyecto acotado, claro, con requisitos muy claros, que comienza y termina y punto... se puede hacer con cierto diseño y arquitectura y el ciclo de vida y metodología que elijas. Proyecto no claro, producto mínimo viable, requisitos impredecibles, reglas de negocio cambiantes... hay que hacerlo con un diseño, concepción y arquitectura totalmente diferente y una metodología ágil más abierta e iterativa. Sutil de pillar, pero con profundas consecuencias en el software que se genera de un modo u otro.

Y esto afecta, claro está, a cómo persisten los datos, cómo se utilizan y cómo evolucionan las bases de datos: al evolucionar las reglas del negocio y funcionalidad, lógicamente, las estructuras de bases de datos (sean las que sean), también cambiarán. Para que esto no suponga una pesadilla, hay que aplicar un enfoque, digamos, más laxo, con sus inconvenientes, claro, pero con las ventajas que comento en este post.

Digresión...

Sé que a algunos les parecerá extraño lo que voy a indicar a continuación, porque va en contra de ciertos paradigmas muy asentados e incluso aprendidos en nuestra etapa académica:

Los modelos de datos relacionales son un obstáculo en sistemas que van a crecer mucho y cuya evolución desconocemos totalmente.

Si cuentas con un proyecto cerrado (se sabe lo que hay que hacer, la lógica de negocio está muy bien especificada, y, además, se entrega y punto, poco más va a ser cambiado), entonces es perfecto utilizar como repositorio de datos con sus entidades relacionadas (relaciones 1..n, 1..1, etc.), que son restricciones sobre el uso y distribución de los datos entre diferentes tablas, manteniendo así en todo momento la integridad referencial y facilitando cosas como la eliminación en cascada, transacciones, rollbacks, etc. Incluso ligar el proyecto a una tecnología concreta de servidor de base de datos (Sql Server, Postgresql, Mongo, etc.)

Sin embargo, siempre (SI-EM-PRE) que he visto un proyecto que ha crecido mucho con funcionalidad inimaginable al principio y se ha querido mantener un enfoque relacional en los datos a toda costa, siempre, digo, el resultado ha sido horroroso: un número exagerado de tablas, reduncancia de datos, complicación extrema en las migraciones y todo cogido con pinzas. Recuerdo ese proyecto con más de cien tablas (sí, más de cien) y tantas líneas indicando sus relaciones que aquello parecía el mapa del metro de Londres. ¿Resultado? Imposible de mantener, cualquier cambio suponía un enorme dolor de cabeza, fallos en producción por efectos colaterales imposibles de prever y ya no hablemos del rendimiento.

En estos casos, hace falta un enfoque diferente, más bien pensar con un paradigma diferente.

Hace falta una componetización radical del sistema, en donde la funcionalidad está distribuida en pequeños componentes que se hablan entre ellos cada uno con su dominio de trabajo. La funcionalidad de alto nivel se implementa mediante la orquestación de los mismos.

Por su parte, puesto que su tamaño es por definición pequeño, cada componente maneja por tanto un conjunto reducido de entidades de datos, sobre los que realiza básicamente actividades CRUD.

Y nada más, porque esta es la clave de construir sistemas grandes que evolucionan mucho.

Este enfoque nos da una libertad extraordinaria para evolucionar el sistema (con más componentes, con cambios en los modelos de datos, etc). En Hub de Libros, sistema donde he empleado claramente este paradigma, además de haber más de setenta componentes actualmente, tan solo dos utilizan en su modelo de datos tres entidades (tablas) diferentes, con poco acoplamiento además y, en total, el sistema cuenta con seis bases de datos diferentes, cada una con un propósito distinto y una política de backups también diferente.

Claro, lo que ganamos por un lado, requiere pagar un precio, como siempre: nos quedamos sin la maravillosa integridad referencial, pero el precio bien vale la pena. Ésta hay que mantenerla programáticamente. No obstante, y después de trabajar en dos proyectos que siguen creciendo con este paradigma, eso no es un problema relevante dadas las ventajas de manejar pequeños modelos de datos para componentes pequeños.

Red Entities, proyecto que ahora libero a la comunidad para su libre uso, permite eso precisamente: definir un esquema (modelo en un objeto json), implementarlo con una línea de código (crear su estructura de datos en Mysql o Sqlite) y una sintaxis insultantemente sencilla y rápida de escribir para realizar las operaciones CRUD habituales, mediante lo que denomino selectores y que me recuerda en cierto modo a la eficacia de jQuery.

Sé que hay otros proyectos similares y mucho más ambiciosos, pero dada la importancia de esta librería en Hub de Libros, decidí desarrollarla desde casi desde cero después de haber trabajado el año anterior en un concepto parecido pero para Redis (Blue Entities) y evolucionarla para no depender en Hub de Libros en este punto tan importante de terceros. No he encontrado, digo, un object-mapper & query builder con las características para implementar componentes como se hace en Hub de Libros y los proyectos en los que trabajaré próximanete dentro de Mantra Framework.

Sin entrar en detalles, punto importante: la actualización de un esquema a otro (por un cambio en una propiedad, otro índice, o cualquier otro cambio), es trivial de realizar, algo que ahora mucho esfuerzo en la vida de cualquier proyecto.

Confío en que sea de utilidad y que haya quienes se animen a utilizar Red Entities en sus propios proyectos.

{ Simplifica }

Un artículo de Rafa G. Blanes

Llevo muchos años estudiando (e implementando) todo lo relacionado con las prácticas de código limpio y de «refactorings», para lo que he escrito muchos artículos así como «El Libro Práctico del Programador Ágil» e impartido varias formaciones.

He descubierto que cuando un programador lleva varios años haciendo algo a «su modo», con sus vicios y virtudes, es muy difícil cambiar su forma de trabajar. Esto es totalmente humano: nos aferramos a lo conocido (aunque intuyamos que ahí afuera hay formas mucho mejores). Te vas a dar cuenta de ello si todos tus proyectos los haces más o menos de la misma forma.

Ignoro si es precisamente por haber roto la barrera de los cuarenta años, pero con el tiempo te vas dando cuenta de que se disfruta más de la vida (de tu hogar, de tu familia y amigos) evitando la complejidad y, quizá, instalando en el día a día cierta rutina productiva y creativa.

Esto es, por alguna razón misteriosa, solemos caer en ese error de creer que algo cuanto más complicado, mejor, cuanto más, aún mejor, sin pararnos a pensar en ello ni vislumbrar la posibilidad de que ese algo, sea lo que sea, se puede hacer de un modo más sencillo y con el mismo resultado.

Recuerdo con cariño a un antiguo compañero de trabajo de una etapa laboral anterior; era muy bueno técnicamente, lo que hacía funcionaba, y lo desarrollaba rápido, pero tenía el problema de que solo lo entendía él. Cualquiera que tuviese que asumir algunos de sus proyectos o librerías, tenía un problema serio.

También me he encontrado, a mi pesar, ciertas actitudes de profesionales que intentan hacer las cosas exageradamente complejas adrede (como si así su valor fuese mayor) y hasta clientes que, al percibir la complejidad de un producto, asocian extrañamente que también su valor es mayor.

Mi opinión es que más que añadir complejidad, hay que quitarla y buscar lo simple. Y aún mejor si es extremadamente simple: en tu trabajo, en la forma de abordar proyectos, y también hacer simple el resto de cosas de nuestra vida, las relaciones familiares, nuestro hogar, nuestros hobbies, etc.

Simple no quiere decir fácil, más bien lo contrario. Buscar la sencillez suele ser algo complejo, por extraño que parezca, al menos al principio.

En los últimos años he leído mucho acerca del minimalismo, «downshifting» y conceptos parecidos, para lo que recomiendo un título que me gustó especialmente: «El Arte de Vivir con Sencillez», de un monje zen japonés de nombre Shunmyo Masuno.

¿Y qué tendrá que ver esa filosofía de vivir de forma sencilla con el desarrollo de software?

Pues todo, porque en definitiva, volcamos en nuestro trabajo nuestro modo de pensar y de actuar. La mente dispersa de una persona poco disciplinada, que divaga, desconcentrada, cuyo escritorio de trabajo es un almacén de recuerdos desordenado y cuyo hogar muestra la misma falta de orden (y limpieza), necesariamente va a impregnar su trabajo creativo con su mismo modo de vida.

Sí, Charles Bukowski, por poner un ejemplo, era un gran escritor, pero también un alcohólico amargado y seguramente un cerdo como persona, pero dejemos a los genios como la excepción que confirma la regla.

De unos años hasta ahora, soy un apasionado de la sencillez y de lo simple, y con el tiempo he descubierto que en el desarrollo de software esto trae muchas más ventajas de lo que pueda parecer al principio.

Hacer un proyecto software sencillo no es trivial, es más, pienso que, al contrario de lo que parece, es algo bastante complicado para lo que hace falta mucha experiencia.

Pero también hace falta buscar la sencillez dedicándole tiempo y parte de las iteraciones de desarrollo.

«Esto ya funciona», me digo a menudo, pero «¿hay algún modo de simplificarlo aún más?»

En la realización de productos que lidero para la empresa que es mi principal cliente, siempre organizo «sprints» para mejorar esto y lo otro antes de avanzar con más funcionalidad y, como consecuencia, la velocidad posterior es mayor (cómo me cuesta trasladar esta idea a los responsables de equipos…).

No es un capricho, es más bien una necesidad, sobre todo en productos y proyectos que sabes que te van a acompañar mucho tiempo o que en algún momento tienes que delegar en otros. Cuanto más sencillo, más barato y fácil será su evolución y con más facilidad otros compañeros asumirán ese trabajo. Hazles un favor y déjales las cosas limpias y ordenadas, te lo agradecerán.

Si necesitas comenzar a delegar para crecer profesionalmente y asumir otro tipo de responsabilidades, todo irá mejor si aquello que delegas puede ser digerido fácilmente por otros. Es decir, esa búsqueda de la sencillez en lo posible, te permite más libertad.

Busco siempre soluciones sencillas, lo más sencillo que se pueda poner en práctica, sin sacrificar, claro está, las buenas prácticas y el buen diseño, hasta el punto en el que si veo un trozo de código con cierta complejidad, no me quedo tranquilo hasta que lo «limpio» y encuentro un modo de simplificarlo, algo que quizá casi nunca te lleva más de un minuto.

Curiosamente, al hacer ese trabajo, descubres que esa forma de afrontar la programación genera diseños más robustos, capaces de abordar muchísimo mejor los cambios en el futuro.

Piénsalo, ¿para qué complicarnos la vida cuando podemos vivir de un modo más simple e igualmente gratificante, o incluso más? ¿Por qué implementar algo de forma rebuscada cuando lo podemos hacer con una sencillez envidiable?

De vez en cuando, me gusta realizar el siguiente ejercicio: navego un poco por GitHub a la caza de proyectos que me llamen la atención. Entro en ellos y, sin saber exactamente qué hacen ni cómo, busco puntos de mejora evidentes (para hacerlos más sencillos), reconociendo rápidamente los «bad smells» (o «malos olores») y tratando de imaginar un modo de hacerlo un poco mejor, refactorizando esto o aquello, cambiando esto otro para que esté más limpio y legible.

En ocasiones, me encuentro con auténticas joyas en este sentido, proyectos admirables de desarrolladores con un código envidiable y muy trabajado. Por extraño que pueda parecer, te puedes preguntar… ¿cómo serán el escritorio y la casa de esta persona? ¿Habrá coherencia entre este magnífico trabajo y su modo de vida? Apuesto a que sí.

Añade sencillez a tu trabajo, a tu organización y metodologías, a tu código, a tu forma de expresarte y de comunicar tus ideas y tus presentaciones, al contenido de tus correos y multiplicarás los resultados de todo tipo.

Solo sobrevive lo simple, lo artificialmente complejo suele terminar abandonado.

«Como haces algo, así lo haces todo»


PD: Este es un capítulo (completo) de «El Arte del Emprendedor Digital».

PD2: También publicado en Medium.

Los que hayan leído mi último libro ("El Arte del Emprendedor Digital"), habrán comprobado por qué es una buena estrategia desglosar la arquitectura de un proyecto software en componentes (sobre todo si el proyecto es de tamaño medio o grande y va a evolucionar mucho). De este modo (y sin entrar en demasiado detalle), la funcionalidad del sistema está ordenada en responsabilidades independientes, fácilmente localizable y modificable.

La clave está en que cada componente (llámalo módulo si quieres), sea pequeño, se encargue de algo muy concreto y específico, y que cuando haya que afrontar una funcionalidad más amplia, se pueda distribuir ésta en varios componentes que se hablan entre ellos. ¿Cómo? Pues según la tecnología y el framework de trabajo que se haya utilizado para implementar este esquema.

Hub de Libros cuenta ahora mismo con más de ochenta componentes, mientras que un proyecto sencillo en el que he trabajado recientemente, tiene ya unos treinta (muchos de ellos reutilizados de otros proyectos).

Puede parecer que se desmadra un poco la cosa cuando hablamos de decenas de módulos independientes, aunque quizá solo los que (como yo) hayan sufrido en alguna ocasión una solución monolítica con mucha funcionalidad (cientos de miles de líneas de código), podrán comprobar las bondades de esta arquitectura. En otro proyecto diferente que he dirigido en Solid Stack, actualmente cuenta ya con más de cien (y subiendo).

Si te enfrentas a un proyecto con cientos de kloc (1 kloc = mil líneas de código) y en él no hueles nada a componente o módulos independientes, malo.

Ahora bien, en todo sistema grande existe funcionalidad de alto nivel que afecta o utiliza un conjunto de funcionalidades de bajo nivel. Tenemos siempre la tentación de implementarla directamente y por separado, y aunque esté encapsulada en su propio componente, finalmente lo que tenemos es, de nuevo, un componente grande y monolítico, más difícil de cambiar, de probar y de evolucionar, y que es justo lo que queremos evitar.

Existe otro enfoque para implementar esa funcionalidad de mayor nivel basado en eventos, esto es, cuando ocurre algo en el sistema, un componente hace algo en concreto y simple, tan solo emite el evento correspondiente por si hay otra parte del sistema que necesita saber que ese evento se ha producido. La gestión de ese evento ni siquiera se tiene que producir en la misma aplicación, sino que pueden existir auténticas infraestructuras software para gestionar eventos en aplicaciones independientes. Redis, sin ir más lejos, permite un esquema de suscripción/publicación que facilita esa comunicación entre procesos para casos en los que hay que gestionar cientos o miles de eventos por segundo.

Por poner un ejemplo, si cuando un usuario se loguea en el sistema hay que guardar cierta información en el log de actividad, o lanzar un informe para su panel de control personalizado o cualquier otra cosa, todo eso no se debe implementar en el mismo componente que se encarga de la seguridad de los usuarios, éste tan solo emite un evento de tipo "users.userloggedin" (es tan solo un nombre descriptivo), y algo en alguna parte del sistema se encargará de realizar lo que haya que hacer cuando eso ocurre.

De este modo, existen componentes base que implementan funcionalidades muy canónicas, pero también, y como parte de una arquitectura bien estructurada en responsabilidades, existen otros componentes que se encargan de implementar funcionalidad de más alto nivel que afecta a grupos de componentes. ¿Cómo? Gestionando eventos y orquestando la funcionalidad de diversos componentes del primer tipo.

Rara es la funcionalidad de alto nivel que no se pueda implementar de este modo. En ocasiones, toda esa funcionalidad de ese tipo, se incluye en lo que se denomina capa de integración, e incluso se implementa bajo el concepto de flujo de trabajo proceso de negocio.

La gestión de esos eventos no tiene por qué ser siempre síncrona (retrasando quizá la interacción del usuario con el sistema), sino que se puede plantear hacerla en segundo plano.

Con esta estrategia, todo sigue encapsulado en componentes sencillos, mientras que aquellos que se encargan de integrar funcionalidad más compleja tan solo orquestan los primeros, manteniendo incluso una implementación sencilla: ante el evento tal, hago esto y después lo otro.

Sin duda, la gestión de eventos y su orquestación son herramientas fundamentales para implementar sistemas software grandes.

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