Practical Object Oriented Design in Ruby – Administrar dependencias

Este post es continuación del ejercicio de parafraseo y resumen del Libro Practical Object-Oriented Design in Ruby escrito por Sandi Metz. El primer capítulo es sobre OOP por lo que me brinque al segundo.

El capítulo tres nos habla acerca de como administrar las dependencias. Empieza por definir que son las dependencias, y como en cualquier aplicación orientado a objetos, los objetos necesitan colaborar y por lo tanto requieren saber unos de otros.

Una clase debe saber sólo lo suficiente para hacer su trabajo y nada más. Regularmente tenemos que preguntarnos que tan “acoplado” está nuestro código o mejor dicho que tan interdependiente se encuentra. Otro manera de evaluar esto es revisar que la llamada Ley de Demeter no sea violada, básicamente es verificar que una clase no mande llamar a otra en más de un nivel, es decir no hacer que un objeto hable con otro y con otro en el mismo método.

Otra importante señal de código muy “acoplado” es la tendencia natural de los nuevos programadores que usan TDD generar pruebas altamente dependientes.

El ejemplo expuesto en el libro, define 4 puntos que son particularmente comunes de encontrar en un código altamente acoplado y son los siguientes:

1.  El hecho de que la clase sepa el nombre de otra clase.

2. El hecho de que la clase sepa el nombre del mensaje que pretende mandar a alguien más diferente de sí mismo.

3. El hecho de que la clase sepa los argumentos que el mensaje requiere.

4. El orden de estos argumentos

Ejemplo antes de refactorizar:

Las recomendaciones para evitar tantas dependencias:

Injección de dependencia, sacar la implementación de la clase externa, pasandola como parametro. Envolviendo las dependencias más vulnerables, es decir aquellas que hacen que cualquier cambio afecte el código en ambas.

Cambiar el orden de los parametros esperados utilizando un hash.

Definir explicitamente valores por defaults en los parametros.

El uso del método fetch para extrar  y validar el valor en la inicialización.

Código refactorizado: