Desde que existe la ingeniería del software, siempre se ha tratado de buscar la mejor manera de construir un software que sea fácilmente sostenible y una de las prácticas de desarrollo más extendidas para conseguirlo es la utilización del diseño orientado a componentes. La idea de construir software “componentizado” no es nada nueva. De hecho, ya en 1968, se empezó a hablar de esta idea para hacer frente a la “crisis del software”, siendo las “tuberías” de UNIX la primera implementación que se conoce basada en esta idea. ¡Me encantan!

En la ingeniería moderna, existen un gran número de principios y patrones que nos ayudan a crear software modular y desde mi punto de vista, los más conocidos aplicables a los lenguajes orientados a objetos son los cinco principios SOLID.

En este post, hablaremos sólo de uno de ellos por estar directamente relacionado con conseguir un diseño desacoplado. Y si la inspiración me acompaña, me reservo un post completo para hablar largo y tendido del resto de principios, que, sin duda, son clave para poder desarrollar software de calidad.

El principio del que quiero hablaros en este post es el relativo a la letra D, o principio “Dependency Inversion” (DIP). La aplicación de este principio, entre otros, nos ayudará mucho a construir software que esté poco acoplado. El acoplamiento es una propiedad del software que mide el grado de dependencia que tienen los componentes que lo forman. Se dice que dos componentes están totalmente desacoplados cuando uno de ellos puede hacer su trabajo sin recurrir al otro. Las ventajas de hacer software con bajo acoplamiento son principalmente que se mejora su mantenibilidad y se incrementa su capacidad de reutilización. Un componente con alto acoplamiento será poco reutilizable y difícilmente mantenible. Y todo esto, traducido al “castellano”, significa que mide cuánto de largos son los “espagueti” de tu plato. ¡Así de simple!

Pues bien, el objetivo de este principio es reducir el acoplamiento entre módulos fomentando el uso de abstracciones para conseguir, que cuando un módulo interactúa con otro, pueda hacerlo sin tener que conocer todos los detalles. De esta forma, los módulos de nivel superior, no dependen de los detalles concretos de implementación, haciéndolos así mucho más reutilizables.

Y como una imagen vale más que mil palabras, prestemos atención a la que se muestra a continuación y reflexionemos: mucho de nuestro software ha terminado así, como unos espaguetis larguísimos y entrelazados. Es decir, código que ha ido creciendo y creciendo indiscriminadamente con un alto grado de dependencia entre sí. Su mantenimiento y evolución llega a ser tan complejo e insostenible que te puede llevar a tener que re-escribirlo completamente.

espagueti-post-sanroman

Ahora bien. ¿Cómo podemos evitar este grado de acoplamiento?

Una vez repasada la teoría, pasemos a la práctica: modelaremos con clases un ejemplo sencillo y aplicaremos, durante la fase de diseño, este principio.

Tenemos dos componentes:

  • Por un lado, el componente vehículo que representa tanto coches como camionetas.
  • Y por otro, el componente motor, que puede ser de combustible o eléctrico.

Y una relación entre ambos componentes: un vehículo tiene instalado un motor debajo del capó.

En el siguiente diagrama de clases puede observarse el diseño resultante con acoplamiento:

diagrama de clases

Este diseño no es correcto porque acopla totalmente el componente vehículo con el componente motor.

Veamos cómo desacoplarlo:

Utilizaremos el principio de Inversión de Dependencia (DIP) y para ello generaremos un interfaz entre ambos componentes (unidad de potencia) y lo “colocaremos” en el módulo de más alto nivel de abstracción, que en este caso es vehículo. De esta forma, invertimos la dependencia entre ambos componentes. Esto permitirá reutilizar el módulo vehículo, sin necesidad de arrastrar el módulo de motor, y rompiendo así nuestro espagueti.

Mirad ahora un diagrama con el nuevo diseño:

diagrama de clases

¿Qué os parece? Al principio parece poco intuitivo, pero poco a poco acaba saliendo de forma natural. Basta con recordar que los módulos de alto nivel no deberían depender de los de bajo nivel y las abstracciones no deberían depender de los detalles.

Aplicando este principio podrás generar software con un acoplamiento bajo y los componentes que lo formen serán mucho más reutilizables.

En uno de mis primeros posts de #{ing}_techit⌝ hablaba de la arquitectura hexagonal o patrón “puertos y adaptadores”, de la que soy un fan total. ¿Os acordáis? Pues en este patrón también es aplicable el principio de inversión de dependencia para reducir el acoplamiento, pero me reservo un post completo para contároslo.

¡Os animo a probar este principio DIP!

Muchas gracias por leerme,

José San Román A. de Lara