¿Qué es el acoplamiento temporal?
El acoplamiento temporal (Temporal Coupling) es un code smell al que no se le presta a veces la atención que merece. Una búsqueda en internet sirve para comprobar que no se escribe mucho al respecto (y menos aún en español). Básicamente consiste en tener un método que requiere de la ejecución de un segundo método antes de poder ser ejecutado.
Por ejemplo:
En este caso no podemos ejecutar el método sendEmail sin antes haber llamado al método init, por lo tanto, hay una acoplamiento temporal entre el método sendEmail y el método init.
Este acoplamiento, además hace que no nos resulte intuitivo el uso de esta clase, ya que lo lógico sería tener la clase ya inicializada.
Una solución muy sencilla para este caso consistiría en hacer el método init privado y llamarlo desde el propio constructor, dejando el objeto ya inicializado correctamente:
Acoplamiento Temporal en la Inyección de Dependencias
Cuando hablamos de inversión de dependencias e inyección de dependencias hablamos de que había dos maneras de inyectar las dependencias:
Vía constructor
Vía setters
Como ya comenté, la inyección a través de setters puede crear un acoplamiento temporal con los métodos que hacen uso de la dependencia:
En este caso si después de instanciar el servicio no inyectamos el repositorio, no vamos a poder registrar el usuario sin obtener una excepción a cambio.
Aquí nos podemos plantear dos soluciones:
Inyectar la dependencia en el constructor (mi opción preferida)
Inyectar la dependencia directamente en el método acoplado.
Esta segunda solución es sencilla de implementar, pero personalmente prefiero que las dependencias queden resueltas en el constructor:
Otras soluciones al acoplamiento temporal
A modo resumen, hemos visto tres posibles soluciones al acoplamiento temporal:
Eliminar la dependencia en el constructor
Inyectar la dependencia directamente en el constructor
Inyectar la dependencia en el método dependiente
Pero aún nos queda una posible solución, que en ocasiones mejora la legibilidad del código, además de eliminar el acoplamiento. Consiste en fusionar los métodos dependientes en un único método y convertir los otros en privados.
En este caso, podemos generar un único método llamado validateAndSave que aúne ambas lógicas, y dado que son dependientes entre si, sería lógico dejar los métodos save y validate como privados.
El resultado es un método semánticamente más correcto y sin dependencias:
Conclusión
Aunque a priori pueda parecer extraño encontrarnos con acoplamiento temporal en nuestro código, hay que prestar atención a las dependencias entre métodos para no caer en este error.
Estos errores suelen ser a veces complicados de encontrar, ya que a veces las excepciones no son muy descriptivas y no nos avisan de esta dependencia. Un mensaje descriptivo en la excepción podría simplificar esto, por ejemplo: Call init() before send and email bastaría para saber por donde van los tiros, Service not available en cambio puede significar mil cosas.
Ahora que sabes algo más del acoplamiento temporal, evítalo usando los métodos que hemos visto ;)
Hasta la próxima!
Top comments (0)