Tuesday, May 26, 2015

Aplicación del principio DRY


Desde siempre he tenido claro que en desarrollo es muy importante que cada concepto este una sola parte del sistema. Por otro lado, también tengo muy presente que la duplicidad de código es un problema y que hay que intentar limitarla y en los casos que sea necesario (casi todos) eliminarla sistemáticamente.

Muchas veces se sigue el concepto DRY a ciegas, sin tener en cuenta que cada decisión tiene un coste, por lo que voy a exponer algunos puntos que pueden ayudar a decidir cuando debemos eliminar la duplicación y cuando podemos vivir con ella.
  • Debemos diferenciar duplicación en conceptos de negocio, reglas, validaciones, flujos, etc y duplicación a nivel de implementación y código donde se pueden dar pequeñas duplicidades. 
  • La duplicidad en conceptos de negocio se debe minimizar todo lo posible.
  • La duplicidad a nivel de código, puede ser una pista de que hay una abstracción pidiendo ser descubierta, un comportamiento emergente del sistema o simplemente un patrón propio de nuestra aplicación. Es importante minimizarla, pero no es un drama si existe algo de duplicidad. Eso si, hay que tener mucho cuidado de no generar una abstracción prematura. En mi experiencia las abstracciones prematuras son mucho peores que la duplicidad.
  • Si haces TDD lo mejor es duplicar el código para conseguir verde y una vez en verde y bien cubierto por los tests, refactorizar eliminando la duplicación.
  • Dependiendo del lenguaje hay duplicidades que tienen un coste elevado de eliminación o que no tienen una solución idiomática en ese lenguaje. En esos casos debemos quitar la duplicidad, si el resultado es más sencillo de entender (no solo por ti, sino por todo el equipo). Ante la duda, debe primar siempre la legibilidad.
  • Es importante saber que cuando eliminamos una duplicidad normalmente lo hacemos creando una clase común, una biblioteca, un método o cualquier otro artefacto que nos permite referenciarlo/usarlo desde varias partes de nuestro código. Esto es una dependencia entre el código cliente y el código a reusado. La dependencia es una de las relaciones más fuertes que se puede dar en el código y siempre es un coste importante así que hay que tener en cuenta este punto a la hora de evaluar si eliminamos la duplicidad o no.
  • Siempre debemos dependender de artefactos que sean más estables que nosotros mismos, es decir si hemos sacado código común a una biblioteca, pero el api de esta biblioteca cambia constantemente es un indicador de que no hemos realizado una buena abstracción y que el coste de mantemiento se nos va a disparar.

Resumiendo:


  • Es importante no tener duplicidad de conceptos de negocio (la duplicidad de bajo nivel es menos importante).
  • Evaluar peligro de abstracción prematura.
  • Evaluar coste añadir dependencia vs ventaja de eliminar duplicidad.
  • Si al eliminar duplicidad se pierde legibilidad, lo estamos haciendo mal.
  • Mejor seguir un proceso de usar, usar, reusar, abstraer (no ir directamente a generar una abstracción).
Si no te puedes permitir esperar un poco antes de hacer una abstracción o una vez que la haces, no te sientes capaz de eliminarla o modificarla en caso de que no se ajuste correctamente a lo que se necesita, tu problema es que estás generando deuda técnica mucho más compleja que la que generas por dejar una pequeña duplicidad.

Aunque el principio DRY puede parecer sencillo de entender, su aplicación, como siempre en el desarrollo de software, no es sencilla ni sistemática.