Curso online de Refactoring de beCode

Esta semana he asistido a otro curso online de beCode, esta vez sobre Refactoring, impartido por Xavi Gost, ese monstruo que vive en una cueva y al que le apasiona el software craftmanship.

¿Qué es refactorizar?

El concepto de Refactoring se lo inventó Martin Fowler hace más de una década. Consiste en mejorar el diseño de un software de forma sistemática, en pequeños pasos, haciendo emerger nuevos refactors y nuevos diseño, pero siempre manteniendo el código correcto.

Martin tiene multitud de seguidores en el mundo del desarrollo de software, siendo Xavi uno de los más aventajados (diría que está a punto de fundar la religión de Martin Fowler). Por otro lado, como dice Jeff Atwood:

Any programmer worth his or her salt should already be refactoring aggressively. It’s so essential to the craft that if you have to read a book to understand how it works, you probably shouldn’t be a programmer in the first place.

O lo que es lo mismo, que aunque no hayas oido nunca la palabra refactoring, si eres programador seguro que ya lo estás aplicando diariamente; y si no es así, estás echando piedras sobre tu propio tejado o el de quien venga detrás, y eso da muy mal karma, que lo sepas. Si quieres saber cómo está tu karma, pregúntate ¿qué le debes al código y qué te debe él a ti?.

¿Por qué refactorizar?

  • Equilibrar el corto con el medio plazo, al mejorar el diseño del código.
  • Para entender el **** código (no sólo tú sino el que venga después).
  • Prevenir el impacto de futuros bugs (sí, que sepas que haberlos los va a haber, pero si te resulta más sencillo encontrarlos, pues mejor, no?).
  • Aumentar la velocidad de desarrollo (unbelievable pero cierto, y más a medio o largo plazo, de hecho el objetivo de tener un buen diseño es desarrollar más rápido).

¿Cuándo refactorizar?

Refactorizar no es un evento, no es algo que te plantees hacer un día, semana o mes determinado. Refactorizar es un proceso, ha de formar parte de tu técnica de desarrollo. Es algo que haces a pequeños impulsos:

  • A nivel de código (o clase), en cuanto detectas algún olor, lo corrijes, el riesgo es bajo y el retorno alto.
  • A nivel de diseño (o relaciones entre clases), hay que ser más precavido y dejar evolucionar el código, para estar seguro de que te duele de verdad. Martin propone la regla del tres: A la tercera vez que hagas algo parecido, refactoriza.
  • A nivel de arquitectura, hay que actuar de inmediato, no queremos construir sobre deuda técnica.

Hay determinadas ocasiones en que merece la pena refactorizar:

  • Al añadir una nueva feature.
  • Al corregir un bug.
  • Al hacer una revisión de código.

¿Cuándo no refactorizar?

No hay que refactorizar cuando sea más adecuado construir otra vez desde cero. No es fácil decidirse entre refactor and rebuild pero como recomendación general, si el código no está funcionando, tiene muchos bugs y no hay manera de estabilizarlo, es probable que lo mejor sea rebuild. Sin embargo, si el código funciona, sí que puedes plantearte refactorizar (recordemos que para poder refactorizar tenemos que partir de código correcto).

Además, en caso de sistemas grandes, un camino muy prometedor es separar en componentes con una fuerte encapsulación y cohesión, para después plantearnos con cada uno si queremos refactorizar o construir desde cero.

Conclusiones del curso

El formato del curso, como ya dije en el anterior, me parece genial, porque permite: reunir a gente con intereses similares sin necesidad de moverse (online) y aprender en pequeñas píldoras pudiendo practicar lo aprendido (una hora cada día). Además, Xavi es muy buen profesor y, sobre todo, tiene mucho que enseñar, con lo que el curso mereció aún más la pena.

En cuanto al plan inicial del curso, hay que decir que no pudimos llegar a la última sesión planificada, y es una pena, porque era una práctica real de refactoring que prometía bastante. Lo que vimos fue lo siguiente:

  • Conceptos y preguntas sobre Refactoring.
  • Olores en el código.
  • Métodos de composición.
  • Moviendo responsabilidades entre objetos.
  • Organizando datos.
  • Simplificando condicionales.
  • Naming.
  • Llamadas a métodos.
  • Generalización.

El código que utilizamos está accesible en mi github, incluyendo enlaces a algunos de los refactorings que practicamos.