Como escribir código mantenible y estable

code

code

A la hora de escribir código que será llevado a producción, es necesario seguir un cierto grado de disciplina que permita que dicho código sea legible, mantenible y correcto. Para esto proponemos una serie de procesos que son, en cierta medida, estándares de facto en empresas punteras en el mundo del desarrollo de software.

La aplicación de éstos de una forma correcta y estricta facilitará la escritura de código que podrá ser mantenible a lo largo de los años, mientras que la no aplicación de dichos procesos y disciplina dificultará en gran medida que el código en cuestión llegue a ser un producto estable y fácil de mantener.

El objetivo de este articulo es permitir entender cómo realizar modificaciones controladas y seguras del código, con el objetivo de poder evitar su desestabilización, así como intentar no llegar a un punto en el cual sea demasiado difícil de mantener. Para ello, vamos a describir una serie de buenas prácticas para usar sistemas de control de código, ya que es un elemento fundamental para poder aplicar el resto de prácticas o procesos y tener una buena gestión del código.

Una vez tenemos dicho proceso, podemos empezar a hablar del ciclo de vida del desarrollo de software, el cual establece una serie de fases así como distintas medidas de calidad requeridas para el código que se modifica. La aplicación de este ciclo de vida será posible gracias al correcto manejo de los sistemas de control de código, así como la aplicación de revisiones de código que permitirán el control de los cambios que se suban al repositorio.

Usar un SCM

La finalidad de un SCM es la de servir como punto de gestión de versiones relativamente estables, atómicas y completas del código. El grado en el que esto debe cumplirse dependerá de la estructura del repositorio en cuestión, procesos de desarrollo, y el producto que se esté desarrollando. Por lo tanto, únicamente los cambios de código que pasan un cierto grado de medidas de calidad deben ser subidos al repositorio.

Otro de los objetivos de un SCM es servir de historial de los cambios realizados en el código. Esto resulta muy útil a la hora de averiguar quién introdujo una determinada funcionalidad y cuándo lo hizo, cuándo se arregló un bug o problema, o cuántas veces se ha refactorizado una porción de código. También es muy útil a la hora de deshacer cambios.

Si el desarrollador en cuestión ha realizado muchos commits, será complicado utilizar esta capacidad de historial que tan útil puede llegar a resultar. Por otro lado, si los commits no son atómicos y contienen varios cambios que afectan a diferentes funcionalidades, será difícil distinguir qué cambios pertenecen a una u otra funcionalidad, y también será complicado revertir las modificaciones a una funcionalidad concreta.

Las revisiones de código: cuatro (o más) ojos ven mejor que dos.

Una vez detallada la funcionalidad de un SCM, podemos entender los beneficios de la aplicación de las revisiones de código. Se trata de uno de los procesos más importantes a la hora de desarrollar software correcto y mantenible, y consiste en solicitar a uno o más miembros del equipo que revisen el código escrito.

Existen dos tipos de revisiones de código, precommit y post-commit. Las primeras ocurren antes de enviar el código nuevo al repositorio, ya que sólo se podrá hacer el commit cuando los revisores hayan aprobado los cambios. Por otro lado las post-commit se realizan después de haberse subido los cambios correspondientes. La finalidad de ambas es muy distinta.

Hay distintas herramientas que se integran con SCMs para realizar el proceso de revisión de código, como por ejemplo Reviewboard, la funcionalidad de pull request de GitHub, rietveld, etc. Estas herramientas permiten visualizar las diferencias que van a ser “commiteadas”, y realizar comentarios en las líneas en cuestión para así permitir la discusión entre autor y revisores.

Las revisiones post-commit, a diferencia de las pre-commit, sirven para realizar discusiones en grupo sobre cambios en el código que ya han sido “commiteados” al repositorio. Tienen varias desventajas, como el hecho de que cambios posteriores requerirán nuevos commits para solventar los problemas detectados, lo cual choca con la definición realizada anteriormente de buenas prácticas para el uso de SCMs.

Además, al estar el código ya subido al repositorio, cabe la posibilidad de que estas revisiones nunca se realicen o que los cambios tampoco se produzcan. Por lo tanto, más que para mejorar la calidad del código, sirven para compartir conocimiento entre los miembros del equipo.

El ciclo de vida: estabilizar para triunfar Otro proceso importante a la hora de escribir código de producción es tener un ciclo de vida definido, con distintas fases en las cuales el grado de permisividad de los cambios que se pueden realizar varíe. Es importante que haya una o varias fases dedicadas a la estabilización del código, donde el objetivo es tratar de resolver problemas o fallos sin introducir funcionalidad nueva.

Para ello habrá que realizar un proceso conocido como bug triaging o bug council, donde se determinará la severidad de cada uno de los bugs, el coste y riesgo de arreglarlo, y el tiempo restante para liberar una nueva versión.

Por lo tanto, cuanto más cerca esté la fecha de release, más severos tendrán que ser los bugs arreglados y menor el riesgo de poder introducir regresiones. Esto supone una política de commits controlados que sería muy difícil de hacer sin las revisiones pre-commit.

Además, esto permitirá que el número de commits decrezca conforme nos acercamos a la fecha de release para así minimizar la variabilidad del código y conseguir que la calidad se vaya estabilizando. Es frecuente observar que, en proyectos donde no existen este tipo de procesos, el número de commits se mantiene estable conforme se acerca la fecha de release, o incluso aumenta, incrementándose la posibilidad de introducción de fallos nuevos y dificultando en gran medida la estabilización de la calidad del producto.