SOLID es el acrónimo que introdujo Robert C. Martin a principios de los años 2000 que representan los cinco principios que debes de considerar en la programación orientada a objetos. Estos principios no son más que guías que puedes o no aplicar en el desarrollo de software, pero que te permiten crear sistemas extensibles, flexibles, legibles y con un código limpio (spoiler: en futuras entradas hablaremos sobre código limpio). Podemos concluir que los principios SOLID nos permiten alto grado de cohesión y bajo acoplamiento.

¿Qué es la cohesión?

La cohesión en términos de informática se refiere al grado en que diferentes elementos de un mismo sistema permanecen unidos generando un elemento mayor. Podríamos verlo como una clase que integra varios métodos y cada uno de estos métodos está relacionado entre sí, teniendo una “temática” común.

¿Qué es el acoplamiento?

El acoplamiento es el grado en que todos estos elementos se relacionan entre sí. Entre mayor sean las relaciones o dependencias mayor grado de acoplamiento tendremos.

Cómo aplicar los principios SOLID en JavaScript

Ya vimos un poco de teoría y ahora nos vamos a enfocar en la práctica. En esta parte de este artículo buscaremos cómo aplicar cada uno de los principios en éste maravilloso lenguaje.

Por cierto, si estás buscando como convertirte en un mejor desarrollador de software, te dejo esta guía que fue escrita en Laserants.

Los cinco principios SOLID son:

  • S – Principio de responsabilidad única (Single responsibility principle)
  • O – Principio de abierto/cerrado (Open/Close principle)
  • L – Principio de sustitución de Liskov (Liskov substitution principle)
  • I – Principio de segregación de la interfaz (Interface segregation principle)
  • D - Principio de inversión de la dependencia (Dependency inversion principle)

Principio de Responsabilidad Única

Nos dice que una clase o función debe centrarse en una única responsabilidad, que debe existir una única razón para cambiar; en resumen podemos decir que éste principio nos pide que todos los métodos o sub-funciones tengan alta cohesión.

En este ejemplo podemos ver como la clase Auto tiene métodos específicos para leer y escribir información, pero no hace nada adicional como guardar en una base de datos, llamar a otras funciones ajenas.

Principio de Abierto/Cerrado

Nos dice que debemos ser capaces de extender el comportamiento de una clase/función sin modificar.

Si quisiéramos a la clase ProductosEnAlacena añadirle la posibilidad de ingresar más productos entonces haríamos lo siguiente:

Como se puede observar, le hemos hecho modificaciones a la clase, sin alterar la funcionalidad previa, cumpliendo así con el principio.

Docker desde cero para desarrolladores - LaserAnts
Los contenedores son ideales para desarrollar aplicaciones portables, aprende docker desde cero para crear y administrar tus aplicaciones en contendores
¿Ya viste nuestro curso de Docker desde cero? Te dejo el link por si estás interesado.

Principio de sustitución de Liskov

El principio nos indica que si estás usando una clase Rectangulo y luego creas otra clase llamada Cuadrado que extiende de Rectangulo entonces cualquier objeto creado a partir de la clase Rectangulo puede ser cambiado por Cuadrado, obligándonos así a que cualquier clase hija no altere el comportamiento de la clase padre.

Entonces tendríamos un rectángulo:

Y tenemos una prueba escrita en mocha para comprobar el área:

Si ejecutamos la prueba nos encontramos que el área debe ser equivalente a 16, resultado de multiplicar ancho (8) por alto (2).

Ahora creamos una clase Cuadrado que extiende de Rectangulo.

Para validar que no rompimos el funcionamiento del padre, correremos la prueba sobre un objeto creado con la clase Cuadrado. Al correr la prueba nos daremos cuenta que ha fallado, pues ahora un cuadrado escribe el ancho y alto como el mismo valor imposibilitando tener el área de un rectángulo con lados diferentes.

Hasta éste punto te estarás preguntando como solucionarlo, y creo que has de estar pensando en diferentes posibilidades. La primera y más sencilla puede ser abstraer la lógica a una clase superior quedando el código de la siguiente manera:

Principio de segregación de la interfaz

El principio nos indica que una clase debe de implementar únicamente las interfaces que necesita, es decir, que no necesite tener que implementar métodos que no utilice. El propósito de este principio es obligarnos a escribir interfaces pequeñas buscando aplicar el principio de cohesión en cada interfaz.

Imaginemos que tenemos un negocio de venta de computadoras de escritorio, sabemos que todas las computadoras deberían de extender de la clase Computadora y tendríamos algo como esto:

En nuestro negocio todo va de maravilla y ahora queremos extender un poco más nuestro catalogo de productos, así que decidimos optar por empezar a vender computadoras portátiles. Un atributo útil de una portátil es el tamaño de la pantalla integrada, pero como bien sabemos esto solo esta presente en las portátiles y no computadoras de escritorio (generalizando), al inicio podemos pensar que una implementación podría ser:

El problema que tenemos con esta implementación es que no todas las clases, por ejemplo la EscritorioDell, requieren los métodos para leer y escribir el tamaño de la pantalla integrada, entonces deberíamos de pensar en separar ambas lógicas en dos interfaces quedando nuestro código así:

Todo suena perfecto, pero ¿te has dado cuenta del problema?, y es que JavaScript solo soporta una clase padre, entonces la solución sería aplicar un mixin, este sería el código utilizando un mixin:

Principio de inversión de dependencia

En este principio se establecen que las dependencias deben de estar en las abstracciones y no en las concreciones, en otras palabras, nos piden que las clases nunca dependan de otras clases y que toda esta relación debe estar en una abstracción. Este principio tiene dos reglas:

  1. Los módulos de alto nivel no deben de depender de módulos de bajo nivel. Esta lógica debe de estar en una abstracción.
  2. Las abstracciones no deben de depender de detalles. Los detalles deberían depender de abstracciones.

Imagina que tenemos una clase que nos permite enviar un correo:

En este ejemplo se puede ver que se está rompiendo la regla, puesto que la clase correo depende del proveedor de servicio, ¿qué pasaría si después queremos usar Yahoo y no Gmail?

Para solucionar esto debemos eliminar esa dependencia y añadirla como una abstracción.

De esta forma ya no nos importa el proveedor ni la forma en que implementa el envío de correos el proveedor, la clase de Correo solo se ocupa de una única cosa, pedirle al proveedor que envíe un correo.

Hasta acá hemos terminado con esta publicación sobre los principios SOLID en Javascript, agradecería que me dejes comentarios y sugerencias sobre que otros temas te interesaría que repasaramos.

6 cosas que puedes hacer para convertirte en un mejor desarrollador de software - LaserAnts
Hace algunos meses me preguntaba acerca del camino que he recorrido en mi carrera como desarrollador de software y podría decir que he sido afortunado pero no soy fiel creyente de la suerte, creo que puedes trazar tu propio camino a partir de todas las decisiones que tomas. Desde que inicié mi carre…
6 cosas que puedes hacer para convertirte en un mejor desarrollador de software