La regla del Boy Scout y la Oxidación del Software

0
11038

Efectivamente y sí, el software se oxida. Y no creo que nadie pueda negarlo porque ¿quién no ha visto como el código de una aplicación se va degradando lenta y sutilmente con el paso del tiempo? Vale, a veces la degradación no es ni lenta ni sutil, pero más a mi favor 😉

Así podríamos decir que si el oxígeno oxida los metales, somos nosotros mismos, los desarrollares, quienes oxidamos el software. Puede que con esta afirmación muchos desarrolladores se escandalicen, pero reconozcamoslo, nosotros somos los únicos responsables de la creación, y modificación, degradación y destrucción del software.

Normalmente producimos esta oxidación por dejadez, vagancia, prisas, desconocimiento, mala praxis, … y en general por una actitud poco profesional. De esta forma vamos realizando pequeños cambios en el código donde para salir del paso metemos un if por allí, una linea extra en un método por acá, un poquito de copy/paste por allá, … Todos estos cambios son en esencia inofensivos, pero la suma de todos ellos tienen consecuencias devastadoras ya que acabamos con los principios SOLID:

Principio de responsabilidad única (Single Responsibility Principle)

Si añades un método, incluso si añades una sola línea a un método, puedes estar añadiendo comportamiento que lógicamente no debería estar en ese módulo (método, clase, paquete, …), violando así el principio de responsabilidad única que nos dice que un módulo debe servir a un único propósito. Este principio permite bajar el acoplamiento y aumenta la flexibilidad de los sistemas, permitiendo cambiar más fácilmente las piezas y haciendo que el impacto del cambio sea mínimo o nulo en el resto del sistema.

Este principio es fundamental para que nuestro sistema sea más fácil de mantener y evolucionar, y ojo porque «más fácil» al final se acaba convirtiendo en más barato 🙂

A mi parecer este principio es posiblemente el más importante, de hecho creo que si cumpliéramos perfectamente este principio el resto de principios SOLID vendrías solos.

Una pista para identificar violaciones de este principio es cuando vemos en nombres de métodos o clases conjunciones del estilo «Y» o «O». Esto suele indicar que el método o la clase está haciendo más de una cosa.

Otra buena manera de saber que estamos cumpliendo con este principio es cuando hemos ido extrayendo responsabilidades hasta el punto de que ya no podemos quitar ninguna más sin que desaparezca el módulo. La última que ha quedado es la responsabilidad única del módulo.

Principio de abierto-cerrado (Open-Closed Principle)

Cada vez que para añadir un nuevo comportamiento estás modificando código, estás violando este principio. Por ejemplo si pones un if para, en función de un parámetro, hacer una cosa u otra cosa nueva.

La forma de perseguir este comportamiento es mediante el uso masivo del polimorfismo. Si conseguimos esconder cada módulo detrás de un contrato o interfaz, será muy fácil añadir nuevos módulos que cumplan el mismo contrato pero que cambien el comportamiento.

Normalmente si hemos violado el principio de responsabilidad única también estaremos violando este principio ya que como los módulos son demasiado grandes y hacen demasiadas cosas, no cumplirán ningún contrato definido y será complicado añadir nuevos módulos con el mismo contrato que realicen nuevos comportamientos.

Principio de sustitución de Liskov (Liskov Substitution Principle)

Con este principio se pretende mejorar las relaciones de herencia. Este principio dice que en cualquier sitio donde podemos usar una clase base, deberíamos poder usar también una clase derivada y que todo funcione como se esperaría con la clase base.

Esto aunque parezca mentira es bastante difícil de conseguir porque significa que tenemos que ser capaces de crear clases hijas que añadan comportamiento (principio abierto-cerrado) y sigan manteniendo válido el comportamiento de la clase que estamos extendiendo; pero desgraciadamente la herencia es una relación muy «fuerte» que nos acopla mucho con la clase que intentamos extender, y por esto es bastante fácil romper su comportamiento.

Voy a poner un ejemplo a ver si se entiende mejor. Imaginar la clase Rectangulo, donde tenemos un setAlto() y un setAncho(). Además en esta clase tenemos un calculaArea(), donde el área será = alto x ancho.

Sería bastante normal tener un código que fije el alto a 3 y el ancho a 2. Si llamamos a calcularArea() el resultado esperado sería 6. 

Ahora podemos pensar que un cuadrado es un tipo de rectángulo que tiene alto y ancho iguales, así que añadimos una clase hija de Rectangulo que llamaremos Cuadrado, donde reescribimos los métodos setAlto y setAncho para garantizar que ambos son siempre iguales.

Pero entonces ¿cómo se comportaría esta nueva clase hija con el código que teníamos antes?!?!?! Si fijamos el alto a 3 y el ancho a 2 y llamamos a calcularArea() el resultado será 4 en lugar de 6!!! (al haber fijado el ancho también hemos modificado el alto).

Con este ejemplo se ve como la clase hija rompe el comportamiento de la clase base. Y el código que ya teníamos escrito deja de ser predecible.

Así que ya sabéis, hay que tener mucho ojo cuando creemos clases hijas.

Principio de segregación de interfaces (Interface Segregation Principle)

Si en un interfaz o contrato añadimos más métodos de los estrictamente necesarios estaremos violando este principio. Un buen indicador de que hemos violado este principio es cuando implementamos una interfaz y lanzamos una excepción o dejamos muchos de sus métodos sin implementar porque no nos interesan. Esto está indicando que la interfaz define métodos con poca cohesión entre ellos ya que se pueden usar unos sin necesitar los otros (y por eso los dejamos en blanco).

Normalmente si vemos una violación de este principio significa también una violación del principio de responsabilidad única ya que el contrato está definiendo demasiado comportamiento.

Principio de inversion de dependencias (Dependency Inversion Principle)

Y por último, pero no por ello el menos importante, el principio de inversión de dependencia (de hecho para mi es mi segundo favorito después del principio de responsabilidad única).

Este principio lucha fervientemente para bajar el acoplamiento entre módulo, de forma que las dependencias de código viajan en un sentido y las dependencias de ejecución dviajan en el sentido contrario. Esto permite cambiar los módulos (principio abierto-cerrado) sin tener que modificar ni una sola línea de código del resto de módulos (para ver un poquito más sobre esto leer el artículo «Orientación a Objetos y la importancia de Tell, Don’t Ask»)

En cuanto un módulo dependa de otro sin haber entre medias un contrato/interfaz, seguramente estaremos violando este principio.

 

Con todo esto podemos ver como cada vez que escribimos una línea de código, si vamos en contra de alguno de los principios mencionados, estamos oxidando el software; en mayor o menor medida, pero tener claro que lo estamos oxidando.

La regla del Boy Scout

Pero Alejandro, otra vez nos la has jugado y nos has contado un rollo sin decir una palabra de «La regla del Boy Scout»!!!

Pues tenéis toda la razón, pero consideraba importante sentar primero las bases de como se oxida el software para poder contaros la regla del Boy Scout. Esta es una regla muy sencilla, consiste simplemente en hacer lo mismo que hacen los Boy Scout cada vez que salen al campo, y es dejar la zona cuando se marchan un poquito mejor de lo que la encontraron al llegar.

Según esta regla nosotros deberíamos actuar igual, y cada vez que tocamos un método, una clase, o en general cualquier módulo deberíamos dejarlo un poquito mejor de lo que lo encontramos para que no se oxide. 

Por supuesto esto lo conseguiremos persiguiendo los principios que hemos visto en el código que escribimos, pero lo que hace interesante la regla del Boy Scout es que no se limita a recoger nuestra propia basura, sino que debemos de recoger y limpiar un poquito de la basura que nos encontramos allí por donde pasamos. Basta con un poquito, no hace falta liarse la manta a la cabeza, simplemente hacer acciones que nos lleven unos pocos minutos, como poner un nombre más expresivo, extraer a un método o a una clase, … Así no sólo prevendremos la oxidación sino que conseguiremos que nuestro software brille como una patena.

 

Dejar respuesta

Please enter your comment!
Please enter your name here