> Escribir código testeable: principio de responsabilidad única
Identifiquemos aquellas clases que erróneamente se encargan de numerosas tareas y desacoplemos funcionalidades
El principio de responsabilidad única (Single Responsability Principle) es un principio de diseño general perteneciente al paradigma de la programación orientada a objetos (POO). Es un término acuñado por el ingeniero de software Robert C. Martin el cual expresó que una clase debería tener solo una razón para ser cambiada.
Este principio establece que queremos aumentar la cohesión entre las cosas que cambian por una misma razón y disminuir el acoplamiento entre las cosas que cambian por diferentes razones. Esto a menudo se parafrasea como “una clase o un método que debe hacer una sola cosa y hacer esa sola cosa muy bien”.
Si bien el principio de responsabilidad única es valioso por una amplia variedad de razones, también es bastante valioso desde el punto de vista de la capacidad de testeo. Cuando violamos el principio de responsabilidad única, se crean algunos problemas para la comprobabilidad de las clases sujetas a prueba.
Primero, las clases con responsabilidades múltiples tienen más funcionalidad que las clases con una sola responsabilidad. Como resultado, nos vemos obligados a probar estas múltiples piezas de funcionalidad dentro de un único arnés de prueba para la clase que nos encontremos testeando. Esto significa que es probable que tengamos más testeos en cada arnés de prueba, lo cual se vuelve en general más difícil de leer, comprender, navegar y mantener, al contrario de un pequeño número de pruebas. Además, si tenemos varias responsabilidades en nuestro caso de prueba, ahora tenemos más cosas que configurar antes de ejecutar nuestras pruebas, esto hace que nuestra lógica de configuración sea más compleja y difícil de seguir.
Finalmente, si tenemos varias razones para tener que cambiar una sola clase, también aumenta la probabilidad de que también tengamos que cambiar la clase en sí, esto significa que la posibilidad de que tengamos que cambiar el dispositivo de prueba y los casos de prueba aumenten.
En última instancia, la violación del principio de responsabilidad única significa que realizaremos cambios frecuentes en una gran cantidad de pruebas con una configuración de las mismas aún más compleja. Esto hace que sea más difícil de generar y mantener los casos de prueba de nuestra aplicación.
SINTOMAS❗
Hay varios síntomas de este problema que debemos vigilar.
- Si alguien nos pide que describamos lo que hace una clase y nuestra descripción contiene los conectores “y / o”, es probable que la clase tenga múltiples responsabilidades. Por ejemplo, una clase que imprime una factura y envía la misma por correo electrónico.
- Los archivos y métodos de una clase que son extensos suelen ser un indicador bastante bueno de que una clase puede tener múltiples responsabilidades. A menudo, las clases grandes y los métodos de prueba contienen varias unidades de funcionalidad que se pueden refactorizar en clases y métodos más pequeños.
- Las clases que tienen muchas dependencias inyectadas en ellas son a menudo una indicación de que una clase está tratando de hacer demasiado. Si bien no hay una regla estricta sobre cuántas dependencias son demasiadas, en general, cuantas más dependencias se inyectan a una clase, mayor es la probabilidad de que sea responsable de más de una cosa.
- Si una clase o un método cambia con frecuencia, puede ser una indicación de que tiene más de una razón para cambiar. Las clases que tienen múltiples responsabilidades generalmente cambian con más frecuencia que las clases con una sola responsabilidad.
Entonces, ¿Cómo refactorizamos una clase que ha violado el principio de responsabilidad única para facilitar nuestras pruebas? 🤔
- 🚀 Identificar las responsabilidades independientes dentro de la clase. Buscar las múltiples razones por las cuales una clase o método podría cambiar, las cuales tal vez nacen de varias personas pertenecientes a diferentes roles de una compañía que quizás soliciten cambios en la clase.
- 🚀 Tratar de etiquetar las responsabilidades. Cuando se encuentra una responsabilidad escondida en otra clase, generalmente se le puede dar un nombre que describa brevemente lo que esta realizando.
- 🚀 Descomponer la clase original en clases individuales, cada una con una sola responsabilidad. Se puede usar la etiqueta pensada en el paso anterior para ayudarse a nombrar las nuevas clases.
Recuerden que a la hora de escribir código y plasmar nuestra lógica es importante tener una mentalidad de testeador, esto nos facilitará aplicar cambios en nuestras aplicaciones en un futuro y no caer en un código fideo que nos quitará el sueño el día de mañana. Como también darnos la seguridad de que lo que realizamos funciona y cumple con lo que nos proponemos. Gracias por leer.