Tag Archives: desarrollo

Código Muerto 💀

Una de las anĂ©cdotas mĂĄs comunes de un proyecto de software es que siempre hay una clase o una funciĂłn que serĂĄ recordada por el nĂșmero de lĂ­neas que esta tuvo. Estoy seguro de que al menos una vez hemos escuchado:

“No toques esa clase, tiene como 1000 lĂ­neas de cĂłdigo”

Developer anĂłnimo

Este es un dato particular de acuerdo a los proyectos en los que estuve y conversaciones entre amigos. Lo que es menos comĂșn, es saber cuĂĄntas lĂ­neas de cĂłdigo tiene el proyecto en el que estamos trabajando.

Si en este momento nos hacemos esa pregunta o se la hacemos a otro miembro del equipo, es posible de que no consigan una respuesta concreta. Si bien es cierto no considero necesario ser 100% precisos, he notado que pocas personas se preocupan de esa mĂ©trica, a menos claro, de que haya algĂșn costo asociado.

Si no les ha pasado, les comento que casos como este se dan desde hace mucho en proyectos donde se audita cĂłdigo. Sin ir muy lejos, Amazon liberĂł [CodeGuru], un servicio (aĂșn en preview) que analiza el cĂłdigo fuente. Como es de esperar, el costo estĂĄ asociado al nĂșmero de lĂ­neas y no es el Ășnico producto o servicio que hace este [tipo de trabajos]

Fuente: [Amazon CodeGuru]

¿Qué es lo que regularmente encontraremos?

He participado en proyectos donde el anĂĄlisis o auditorĂ­a de calidad de software era uno de los objetivos mĂĄs importantes. Muchas veces el costo de servicios adquiridos –u ofrecidos– estaba relacionado al nĂșmero de lĂ­neas de cĂłdigo (o LoC por [Lines of Code]).

En cada trabajo era comĂșn confirmar lo encontrado en proyectos anteriores:

  1. Pocas personas conocĂ­an el nĂșmero de LoC o la importancia de este indicador
  1. Una prĂĄctica conocida –y en algunos casos, aceptada– era “agregar cĂłdigo de ejemplo, ir cambiando y probando pero guardar la versiĂłn original por si algo se malograba”
  1. Muchas veces se mantenĂ­an las carpetas de plantillas y ejemplos de las librerĂ­as y componentes de terceros que en algunos casos ya no se utilizaban

Ya en un caso concreto, estuve en un proyecto donde el desarrollo tenĂ­a mĂĄs de un millĂłn de LoC y estaba seguro de que eso no podĂ­a ser posible pues las funcionalidades del sistema no reflejaban dicha realidad.

SabĂ­a que estaba frente a un caso de CĂłdigo Muerto, pero tenĂ­a que demostrarlo.

¿Qué es Código Muerto?

Sin entrar en detalles (pues es posible que encuentren discrepancias y hasta [una canciĂłn]), el cĂłdigo muerto o “Dead Code” es aquel que no aporta valor al negocio.

El cĂłdigo muerto se puede clasificar de la siguiente manera:

  • CĂłdigo que no se usa: Muy usual en los proyectos de software, algunas veces no se recuerda su objetivo inicial y por lo general ocurre pues las necesidades van cambiando y el cĂłdigo no se depura adecuadamente luego de cada cambio (mucho cuidado con las frases “es que no hay tiempo” o “lo vemos despuĂ©s”)
  • CĂłdigo que se ejecuta pero que no se usa: AquĂ­ entran los casos como los de variables asignadas o llamadas a funciones cuyo resultado no es utilizado. Esto es nocivo pues ademĂĄs ser cĂłdigo inĂștil, consume recursos del sistema.

ÂżCĂłmo identificar CĂłdigo Muerto?

Con el paso del tiempo preparĂ© una secuencia de anĂĄlisis que me sirviĂł para encontrar casos de cĂłdigo muerto bajo la premisa de que si algo se define en el programa, este debe ser utilizado de manera efectiva. La lista puede parecer obvia, pero ya estĂĄ demostrado que en tecnologĂ­a no debemos confiar en las obviedades 🙂

  • Variables
  • Funciones
  • Clases
  • Comentarios (sean redundantes o cĂłdigo que fue comentado para ser utilizado “mĂĄs adelante”)
  • Elementos de archivos de configuraciĂłn (por ejemplo, secciones comentads o que ya no se utilizan)
  • Archivos de configuraciĂłn
  • LibrerĂ­as (componentes de terceros)
  • Elementos idĂ©nticos (funciones, clases archivos, librerĂ­as o carpetas distribuidos en ubicaciones distintas)
  • Elementos parecidos (librerĂ­as con versiones diferentes, funciones o clases que inicialmente eran una copia de la otra)
  • Carpetas y archivos varios que poco a poco quedan relegados hasta el olvido

Un hecho comĂșn en todos los casos, es que el cĂłdigo muerto existe debido al temor a perder cĂłdigo o a malograr el sistema construido. Esto tiene relaciĂłn directa con el desconocimiento de que los gestores de versiones permiten volver al pasado si es que se necesita ver algo que ha sido borrado.

Otra consecuencia es que a mĂĄs cĂłdigo muerto, mĂĄs complejo serĂĄ el entendimiento de nuestro sistema, la mantenibilidad serĂĄ afectada y a su vez generarĂĄ dependencias con un programador en particular (a veces pueden ser mĂĄs personas). Recuerden, el cĂłdigo es de todos los miembros del equipo y mientras menos dependencias, mejor.

¿Qué herramientas debemos usar?

Puede que parezca una broma, pero un elemento muy importante es la inspecciĂłn visual. A pesar de ello, esta debe pasar a segundo plano pues debemos evitar confiar totalmente de los presentimientos o “literalmente” de puntos de vista.

De acuerdo a esta premisa, lo primero que debemos hacer es trabajar con [herramientas de anĂĄlisis estĂĄtico] que nos brinden un enfoque acertado de lo que estĂĄ ocurriendo.

A pesar de ello, hasta el momento no he encontrado una herramienta que brinde un indicador de cĂłdigo muerto bajo un enfoque holĂ­stico. Es asĂ­ que utilizo principalmente [SonarQube] como base del trabajo a realizar.

Regresando al caso del millón de LoC, encontré pistas que me ayudaron a confirmar la existencia del temible código muerto.

Si queremos empezar con estas prĂĄcticas, algo que nos podrĂ­a ayudar estĂĄ incluido en las herramientas del navegador web. Una de las que ha llamado mi atenciĂłn es la utilizada para analizar la cobertura de los archivos JavaScript y CSS. Esta viene en [Chrome] y no es complicado de usar/entender.

¿Qué conseguí luego de presentar lo encontrado?

El objetivo de mi trabajo en dicho proyecto, fue preparar un informe sobre lo que se estaba construyendo y sobre eso un plan de trabajo para implementar una nueva arquitectura. No me parecĂ­a adecuado llegar con una presentaciĂłn llena de indicadores ni menos señalar responsables (aunque en algunos casos ese ha sido mi trabajo), asĂ­ que gracias al apoyo y explicaciones que el equipo dio cuando estaba analizando el cĂłdigo, tenĂ­a el conocimiento necesario para “limpiarlo”, al menos en casos que parecĂ­an obvios o donde veĂ­a que complejidad baja o media.

Como este tipo de trabajos me gustan, no parĂ© hasta eliminar 95% del cĂłdigo del sistema. No esperaba llegar a ese nĂșmero pero mĂĄs de un millĂłn lĂ­neas era cĂłdigo muerto que se podĂ­a limpiar fĂĄcilmente.

Nada mejor que llegar con un informe que tenga un entregable como ese 🙂

La buena noticias es que el equipo quedó sorprendido. Cuåndo me preguntaron cómo lo hice, les comenté que empecé por las obviedades (y ya saben lo que pienso de ellas :)) creo que eso los animó a seguir limpiando (luego de una segunda limpieza el código no superaba las 30 mil LoC)

¿Qué es lo que aprendí?

  • Es posible que este tipo de trabajos sea incomprendido al principio, pero se consigue mucho enseñando con el ejemplo. En dicho proyecto tenĂ­a que preparar una arquitectura que aproveche lo que ya estaba construido, pero ante las sospechas de cĂłdigo muerto, decidĂ­ detenerme un momento y evaluar cĂłmo eliminarlo, primero por mi cuenta y luego con el equipo.
  • Lo que he encontrado en muchos casos, es que hay pocas intenciones de refactorizaciĂłn que a veces no se dan por el uso desmedido de frameworks y herramientas. Lo que creo que se debe hacer es sentar una base medible de lo que estĂĄ sucediendo sin olvidar que lo mĂĄs se hace en un proyecto de software es la construcciĂłn del mismo. Si es asĂ­ Âżpor quĂ© no saber cĂłmo va creciendo nuestro cĂłdigo?
  • La automatizaciĂłn de pruebas es muy importante pero esta se debe postergar si hay casos obvios de cĂłdigo muerto, he comprobado que a veces resulta mĂĄs rĂĄpido borrar (sin miedo) que ponermos a programar un caso de prueba.
  • Siempre debemos utilizar un gestor de versiones (personalmente prefiero Git sobre GitHub) y tenerlo enlazado a un motor de automatizaciĂłn (como [Jenkins] o [Azure DevOps], ambos me parecen buenos y Azure DevOps es mĂĄs sencillo de configurar) que ayude a tener visibilidad de la integraciĂłn continua.
  • El equipo de desarrollo pasa a otro nivel de conocimiento, pues ademĂĄs de entender la importancia de prĂĄcticas de limpieza de cĂłdigo muerto se abre una nueva puerta hacia la calidad del producto.
  • Si la confianza y comunicaciĂłn son las adecuadas, este tipo de situaciones se convierten en anĂ©cdotas del equipo.

ÂżCuĂĄl fue mi reflexiĂłn final?

Antes de refactorizar o hacer lo que sea en el sistema, eliminen el CĂłdigo Muerto, no teman.

Un abrazo,

Fuente imagen cabecera: [Finding Dead Code]

ÂżCĂłmo practicas programaciĂłn?

Les cuento que casi todo este año tuve el tiempo necesario para programar al menos dos horas al dĂ­a. En tĂ©rminos simples, programar es uno de los hobbies que he ido desarrollando a lo largo de mi vida 🙂

En fin, como algunos saben, hace unos meses estuve en el bootcamp de [42 Silicon Valley] y si bien es cierto no he tenido la oportunidad de escribir al respecto, puedo adelantar que mi aficiĂłn por la programaciĂłn se reforzĂł de tal manera que ahora veo de forma diferente cualquier lenguaje de programaciĂłn, estudio mucho mĂĄs al respecto y si fuera necesario, reviso cĂłmo hacer las cosas con la menor cantidad de librerĂ­as y/o frameworks (pues ahora casi todo se resuelve asĂ­)

Bueno, para hacer la historia corta, mi interĂ©s –y cariño– por el [lenguaje C] ha vuelto, asĂ­ que he propuesto cuatro problemas que parecen simples, pero si intentas resolverlos con la menor cantidad de cĂłdigo, librerĂ­as y ademĂĄs buscas hacerlo entendible, pues ahĂ­ llega la complejidad. De estos problemas ya he resuelto dos y los he dejado en un repositorio esperando que alguien quiera unirse para al menos proponer nuevos problemas. Por mi parte ya tengo algunos en mente, pero tengo que ponerlos en limpio.

En fin, si les interesa este es el repositorio que siempre voy actualizando: https://github.com/jersson/c-problems/tree/dev

Ahora, si quieren ver cĂłmo funciona el cĂłdigo y no quieren clonarlo, aquĂ­ un espacio para jugar usando el navegador https://repl.it/@jersson1/c-problems. De ser asĂ­, tengan especial atenciĂłn en el archivo .replit

Como ya deben haber notado, la documentaciĂłn la estoy escribiendo en inglĂ©s pues ademĂĄs me pareciĂł buena oportunidad para practicar el idioma 🙂

Espero que puedan unirse y que ademås pasen unas excelentes fiestas navideñas.

Un abrazo,

Fuente imagen cabecera: http://offeman.com/safe-casting-pointers-in-object-pascal/

¿Qué tanto le debes a tu sistema?

En términos simples, la deuda técnica tiene que ver con el tiempo que tendrías que invertir para solucionar problemas que estås dejando de lado a nombre de generar un resultado en el menor tiempo posible.

SĂ­, con esto me refiero a las consecuencias del “dĂ©jalo ahĂ­, luego lo arreglamos”

Lo que me he encontrado es que esa es una frase que es aceptada hasta que los problemas se empiezan a poner serios. Por otro lado, hay que considerar que si queremos mejorar “algo”, pues tenemos que saber cĂłmo medir ese “algo” antes y despuĂ©s de los cambios realizados.

ÂżCĂłmo mido un sistema?

Estoy seguro de que hay muchas formas para eso, pero aquĂ­ los pasos que sigo regularmente:

  1. Perspectiva del usuario final
  2. Comportamiento en tiempo real (anĂĄlisis dinĂĄmico de cĂłdigo)
  3. Perspectiva del desarrollador (anĂĄlisis estĂĄtico de cĂłdigo)

1. Perspectiva del usuario final

Asumiendo de que el usuario estĂĄ contento con las funcionalidades existentes y de que no hay errores en producciĂłn (SĂ­, es un gran supuesto), lo que normalmente sugiero es tomar nota del comportamiento de la aplicaciĂłn.

¿Qué se hace ahí? Pues se mide lo que llega al usuario ¿Cómo medimos la aplicación? Para nuestra suerte, si estamos trabajando con una aplicación web, existen herramientas gratuitas que nos permiten tener reportes como el que nos genera [GTmetrix]

Fuente: [AnĂĄlisis del blog personal]

Parece obvio, pero les cuento que he estado en proyectos en los que no se habĂ­a considerado una revisiĂłn bajo esa perspectiva y ya se tenĂ­an quejas de que “el sistema estaba lento”

Lo bueno de herramientas como GTmetrix, es que brindan una mirada objetiva de lo que le entregas al consumidor final. Aquí es donde encontrarås aspectos como el tiempo de carga de la pågina (Fully Loaded Time) o incluso el tamaño de lo que se descarga al navegador (Total Page Size)

Por otro lado, GTmetrix incluye una serie de anĂĄlisis usando herramientas como [PageSpeed] o [YSlow]. Para ambos casos se genera un score que puede mejorarse si sigues las recomendaciones que, para tener una idea, se crearon bajo estĂĄndares de Google (para el caso de PageSpeed) o Yahoo! (para el caso de YSlow)

Otra opciĂłn interesante viene con Google Chrome y se puede usar desde la opciĂłn Developer Tools/Audits, lo cual, en resumen, hace uso de [Lighthouse], que tambiĂ©n es usado por Google PageSpeed 🙂

Fuente: Archivo personal

Los que me conocen saben del cariño que le tengo a YSlow y que me apena que ya no haya una extensiĂłn de navegador para hacer un anĂĄlisis a ese nivel de detalle. Tiempos aquellos 🙂

Update: Si pueden denle una oportunidad a https://yellowlab.tools/ Se ve muy interesante!

2. Comportamiento en tiempo real (anĂĄlisis dinĂĄmico)

Una vĂ­a rĂĄpida para reaccionar a lo que le ocurre al sistema, es saber lo que le pasa a este mientras va funcionando. No soy partidario de esta forma de trabajo, pero en sistemas que ya se estĂĄn ejecutando en producciĂłn es importante contar con al menos una herramienta que permita tener una vista de ese tipo.

AquĂ­ es donde hablamos del anĂĄlisis dinĂĄmico del cĂłdigo con herramientas del tipo APM (Application Performance Monitor). Una que hace muy bien ese trabajo es [New Relic]

Fuente: [New Relic]

La importancia de este tipo de herramientas radica que no son invasivas. Es decir, no tienes que tocar tu código y la performance de la aplicación no se ve afectada. Antes de New Relic probé otros analizadores que degradaban la aplicación al punto que decidíamos desactivar el analizador.

3. Perspectiva del desarrollador (anĂĄlisis estĂĄtico)

Tal como mencioné en la sección anterior, no soy partidario de ir reaccionando acorde a lo que le ocurra al sistema pues creo firmemente que la mejor forma de solucionar un problema es evitåndolo.

Bajo esa premisa estamos en la obligaciĂłn de encontrar mecanismos que permitan controlar lo que se estĂĄ construyendo o modificando. AquĂ­ es donde entran herramientas como [SonarQube]

Fuente: Archivo personal

Lo bueno de esta herramienta (entre muchas cosas) es que te ayuda a clasificar los posibles problemas de programación y te da una estimación base de lo que necesitarías para cubrir esa deuda técnica.

¿Qué ocurre normalmente?

Lo que he encontrado en algunos proyectos es:

  1. No se mide lo que se estĂĄ construyendo
  2. Se mide lo que se construye pero en términos de deuda técnica convencional (anålisis eståtico con SonarQube)

No pondré en duda si se toma acción sobre la deuda técnica pero lo que regularmete encuentro es que se pierde la perspectiva de lo que ocurre en producción o se hace a consecuencia de un problema.

¿Qué estamos perdiendo?

No soy un experto en el tema pero les puedo asegurar que poco a poco iremos perdiendo el control de nuestra aplicaciĂłn analizada. No he encontrado un estudio detallado del impacto financiero al respecto, pero valgan verdades hay situaciones en las que el equipo de desarrollo sugerirĂĄ rehacer un componente/servicio/mĂłdulo/aplicaciĂłn a consecuencia de que lo encontrado es inmantenible.

¿Se imaginan eso en términos financieros? Pues ahí un primer vistazo al dinero perdido a consecuencia de una deuda técnica mal gestionada.

¿Qué tenemos que hacer?

La primera respuesta es obvia, “tenemos que medir nuestra aplicaciĂłn” pero en realidad, ademĂĄs de invertir para lograrlo, hay mucho por hacer al respecto pues lamentablemente no he encontrado una herramienta que nos muestre lo que es realmente la deuda tĂ©cnica. Si bien es cierto SonarQube nos da una idea al respecto, pero no podemos confiar en ese Ășnico indicador (Resumen, SonarQube te ayuda pero no es la soluciĂłn definitiva â˜č)

La segunda respuesta tiene que ver con lo que algunos llamamos el diseño y ejecución de nuestro plan de pagos. Es decir ¿cómo vamos a ir pagando nuestra deuda técnica?

Es aquĂ­ donde tenermos una [gran responsabilidad], pues ademĂĄs de englobar esta serie de issues/riesgos/problemas/bugs tenemos que darle forma al indicador y a su impacto tĂ©cnico/financiero. Por otro lado, debemos aceptar que siempre estarĂĄ ahĂ­ pues estoy seguro de que no hay proyecto que elimine la deuda por completo. Es decir, siempre habrĂĄn issues con los que tendremos que convivir, pero si es asĂ­, tiene que ser una convivencia sana 🙂

Un abrazo,