La  calidad  es  un  concepto  relativo  y  multidimensional,  referido  a  las  expectativas  y  cualidades solicitados por el cliente, a su vez, está ligada a restricciones y compromisos (presupuesto y tiempo de  desarrollo,  entre  otros).  Sin  embargo,  existe  algo  que  nadie  puede  negar,  cuando  algo  es  de calidad  suele  pasar  desapercibido,  pero,  por  el  contrario,  la  mala  calidad  es  algo  que destaca negativamente.

Durante  el  proceso  de  desarrollo  de  una  aplicación,  es  muy  probable  la aparición  de  bugs causados  por  fallos  humanos.  A  su  vez,  las  exigencias  del  usuario  cada  vez  se  incrementan, exigiendo una mejor performance de las aplicaciones que creamos. Pero, ¿cómo podemos entonces mejorar la calidad de nuestras aplicaciones? Justamente,  para  producir  software  de  calidad  y  cumplir  con  la  expectativas  de  nuestros  usuarios es que existen diferentes métricas de calidad de software. Métricas de calidad de software es un conjunto de medidas utilizadas para estimar la calidad de un proyecto   a   desarrollar,   entre   otros   conceptos,   y   que   permiten   comparar   o   planificar   estas aplicaciones.

Es  una  propiedad  de  la  aplicación  compleja,  ya  que  no  existe  una  precisión  absoluta  para determinar  cuáles  son  los  elementos  o  procedimientos  relevantes  que  deben  ser  aplicados  a  la hora  de  escribir  código. También,  es  necesario  definir  las  acciones  a  tomar  dependiendo  de  los resultados de estas métricas.

Existen  diferentes  herramientas  que  nos  ayudan  en  la  tarea  de  mejorar  el  desarrollo  de  nuestras aplicaciones.  En  Ruby,  Rubocop,  Rubicritic,  Bullet  son  algunas  que  pueden  salvarnos  el  día  y ayudarnos a optimizar nuestro código. Pero lo que hacen estas herramientas no es magia.

A continuación describiremos algunas de las principales métricas utilizadas por estas herramientas para determinar la calidad del código producido.

Acoplamiento

“Hay  dos  formas  de  diseñar  software:  la  primera  es  hacerlo  tan  simple  que  obviamente  no hay  deficiencias  y  la  segunda  es  hacerlo  tan  complicado  que  no  hay  deficiencias  obvias.  La primera forma es mucho más difícil.” C.A.R. Hoare

Acoplamiento  (Coupling)  se  refiere  al  nivel  de  “conectividad”  de  un  módulo  con  otros  módulos, datos globales y entorno exterior. Durante  el  desarrollo  de  la  aplicación, uno  de  los  objetivos  es  mantener  una  baja  dependencia  o acoplamiento, esto quiere decir que, un módulo debe ser capaz de interactuar con otro a través de una interfaz estable y sin depender de otros, para su correcta implementación. Por el contrario, un sistema con un nivel de acoplamiento alto tendrá módulos que se encontrarán inter ligados entre sí y se comunicarán directamente unos con otros sin ningún tipo de barrera, por lo que el código será  difícil  de  comprender,  reutilizar,  y  al  no  estar  aislados,  se  deben  considerar  todas  sus dependencias.

Un problema común con este tipo de aplicaciones es que, en caso de un cambio en algún módulo, puede  desencadenar  un  efecto  dominó  en  otros  módulos,  por  lo  que  será  necesario  rehacer código en el resto de los módulos dependientes.

Un código acoplado va directamente en contra del principio “Tell, Don’t Ask” (TDA), que promueve el encapsulado conjunto de los datos y de las funciones que operan sobre estos datos.

Cohesión

Cohesión (Cohesion) define el grado de relación que existe entre los elementos de un módulo.

Un  módulo  que  siga  el  Principio  de  Responsabilidad  Única  o  SRP  por  sus  siglas  en  ingles  debe realizar una única cosa. Es muy habitual, si no prestamos atención a esto, que acabemos teniendo clases que tienen varias responsabilidades lógicas a la vez.

Cuando se tienen clases con baja cohesión implica, entre otras cosas:

  • Falta de comprensibilidad
  • Difícil mantención
  • Difícil reutilización de código

Complejidad

“Cualquier    tonto    puede    escribir    código    que    un    ordenador    entiende.    Los    buenos programadores escriben código que los humanos pueden entender.” Martin Fowler

Una  de  las  métricas  más  importantes  con  la  que  contamos  en  el  desarrollo  es  la complejidad ciclomática, que puede ser usada en las fases de desarrollo o mantenimiento entre otras.

Esta métrica, propuesta por Thomas McCabe en 1976, se basa en el diagrama de flujo determinado por  las  estructuras  de  control  de  un  determinado  código.  Del  análisis  de  esta  estructura  se obtendrán las medidas cuantitativas que nos facilitarán la comprensión y mejora de las mismas.

La  complejidad  ciclomática  está  fuertemente  relacionada  a  un  algoritmo  claro  y  eficaz,  que,  a  su vez, se relaciona a otro tipo de complejidad, la complejidad cognitiva.

Existen   diferentes   prácticas   que   ayudan   a   bajar   esta   complejidad   cognitiva,   la   que   más agradecemos, como desarrolladores, son los comentarios en el código.

La  Complejidad  Cognitiva  mide  que  tan  difícil  es  entender  intuitivamente  un  bloque  de  código,  a diferencia de la Complejidad Ciclomática, que determina qué dificultad tiene probar el código.

Algunos  estudios  han  probado  una  correlación  directa  entre  la  complejidad  ciclomática  y  la cantidad de bugs de un trozo de código, o el numero de líneas de este. Por esto podemos concluir que,  a  mayor  complejidad  y  dimensión,  se  presentan  mayores  problemas  y  fallos  en nuestro código.

Code Churn

Es  la  frecuencia  con  la  que  se  añade,  quita  o  altera  el  código  a  través  del  tiempo.  En  palabras simples, es la cantidad de veces en la que el fichero ha sido modificado.

Esta métrica presenta una relación directa con código defectuoso. esto quiere decir, mientras más modificaciones sufra un código, mayor es la posibilidad de introducir un bug.

Esta  métrica  es  fácil  de  calcular  usando  un  sistema  de  control  de  versiones  (git,  mercurial).  Basta contabilizar el numero de commits que modificaron un dato, fichero, o toda una clase.

Code Coverage

Mide el porcentaje de código que se encuentra testeado. Tener test de calidad en nuestro proyecto, ayudará  a  incrementar  el  valor  de  esta  métrica  y,  a  su  vez,  será  menos  probable  que  el código contenga bugs.

Código Muerto

El  código  muerto  (Dead  code)  es  código  que  no  es  ejecutado.  Es  difícil  de  identificar  ya  que,  no siempre sabemos si cierto extracto de código se está ejecutando en producción o no. Esta métrica es útil para verificar la calidad del código, sin embargo, no existe ningún método que detecte este código muerto y sea infalible.

Por  ejemplo,  puede  haber  código  que  solo  es  ejecutado  por  herramientas  o  servicios  externos,  y que se encuentran fuera del control de herramientas que determinan si el código es utilizado o no. De ese modo se pueden gatillar falsos positivos.

Algunos  desarrolladores  tiene  la  técnica  “borrar,  cerrar  y  cruzar”  y  que  no  es  más  que  borrar  el código sospechoso, cerrar los ojos y cruzar los dedos para que nada se caiga… Claramente esta no es una técnica recomendable.

Tener pruebas automatizadas nos ayudarán a detectar potenciales errores al borrar código.

Duplicación de Código

“Medir el progreso de la programación por líneas de código es como medir el progreso en la construcción de aviones por el peso.” Bill Gates.

Código duplicado  (Code  duplication)  es  el  término  utilizado  para  una  estructura  de  código  que  se declara  más  de  una  vez  dentro  de  una  aplicación.  La  existencia  del  código  duplicado  ocurre frecuentemente  cuando  el  programador  no  está  familiarizado  con  el  código,  lo  que  lo  lleva  a replicar trozos de código. Es importante entender que código duplicado no es exactamente código exáctamente igual, sino que puede ser código con ligeras adaptaciones.

Probablemente, el mayor enemigo del código limpio es el código duplicado. El principio DRY (Don’t Repeat Yourself) viene a nuestro rescate.

La  existencia  de  código  duplicado  afecta  a  los  costos  del  proceso,  ya  que  provocará  una  mayor complejidad  ciclomática,  un  mayor  número  de  pruebas  unitarias,  aumenta  innecesariamente  el tamaño del proyecto, y es mas difícil de modificar, ya que hacerlo implica cambiar todas las copias, lo  que  podría  inducir  al  error  ya que  el  programador  podría  olvidar  realizar  las  modificaciones correspondientes donde se encuentra el código duplicado (shit happens).

¿Cuáles son los beneficios de aplicar métricas?

Una  organización  que  aplica  métricas  en  sus  procesos  busca  incrementar  el  retorno  de  la inversión, identificar las áreas a mejorar, optimizar el tiempo invertido en el proceso, y reducir los costos de operación.

Al  aplicar  estas  métricas,  mejoraremos  la  comunicación,  ya  que  sabremos  el  real  estado  de nuestros  proyectos,  ayudándonos  a  mejorar  la  estimación  de  tiempos  de  desarrollo, prevenir posibles  fallos,  reducir  costos  y  mejorar  el  manejo  del  proceso  priorizando  los  puntos  realmente importantes.

Tal  como  se  indica  en  un  principio  de  este  artículo,  cada  vez  es  más  común  utilizar  herramientas,con métricas mucho mas exactas, que nos permiten optimizar nuestro código.

Lamentablemente,  ni  siquiera  las  mejores  métricas  garantizarán  una  aplicación  exitosa.  Sin embargo,  la  combinación  de  estas  métricas,  un  buen  proceso  de  trabajo,  la  aplicación  de  buenas prácticas  al  programar,  y  pasión  por  nuestro  proyecto,  nos  ayudará  a  entregar  una  aplicación  de calidad al usuario final, dándole un valor adicional a nuestro trabajo.

“Si  deseas  empezar  y  desarrollar  algo  grandioso,  no  necesitas  millones  de  dólares  de capitalización.  Necesitas  suficiente  pizza  y  Diet  Coke  en  la  nevera,  una  PC  barata  y  trabajo  y dedicación para realizar tu idea.” John Carmack

En un próximo articulo conoceremos algunas de estas herramientas que nos permitirán optimizar nuestro código en Ruby on Rails.


Fuentes y referencias

https://estudogeral.sib.uc.pt/bitstream/10316/35523/1/Automacao%20da%20analise%20de%20qualidade%20de%20codigo.pdf

https://www.tutorialspoint.com/software_quality_management/software_quality_management_metrics.htm

https://github.com/whitesmith/rubycritic/blob/master/docs/core-metrics.md

https://blog.powerdata.es/el-valor-de-la-gestion-de-datos/metricas-de-calidad-de-software-una-solucion-excelente

https://cdn.oreillystatic.com/en/assets/1/event/13/Rails%20Software%20Metrics%20Presentation.pdf

https://subvisual.co/blog/posts/19-solid-principles-in-ruby/

Share Button

Desarrollador Ruby on Rails. Deportista por excelencia (si es que se pueden considerar deporte los juegos en línea y codear). Música, códigos y café, la mejor combinación. Fanático de la tecnología y nuevos desafíos. Me encantan las pastas, sobre todo la lasagna.