+34 689 92 10 22

¿Qué son los principios SOLID?

¿Qué son los principios SOLID?

En ingeniería del software, el acrónimo SOLID introducido por Robert C. Martin (uncle Bob), representa cinco principios básicos de la programación orientada a objetos. Cuando estos principios se aplican en conjunto es más probable que se cree un sistema más fácil de mantener y ampliar.

Vamos a repasarlos 😊

Single responsability

Es el principio de responsabilidad única, esto implica que cada objeto debe tener una responsabilidad única. 

  • Código inicial: La clase “Factura” permite tanto el acceso a las propiedades como a operaciones sobre base de datos… ¡2 responsabilidades!

 

  • Mejora planteada: Es siempre mejor separar para que cada objeto tenga su responsabilidad.

Open – Closed

Método implementado, método cerrado. Salvo para subsanar errores o alguna refactorización, no deberíamos modificar comportamientos existentes.

Código inicial: Se nos solicita imprimir cada una de las líneas con un formato específico.

Vale, pero ahora nos dicen que añadamos un nuevo impuesto.

Liskov substitution

En 1987, Barbara Liskov en una conferencia introduciría el siguiente concepto: “Los objetos de un programa deberían ser intercambiables por instancias de sus subtipos sin alterar el correcto funcionamiento del programa”.

En resumen: si la clase B y C heredan de la A, el programa debe de poder usar B o C indistintamente. Esto es un uso correcto de herencia y polimorfismo.

Si ponemos un ejemplo con vehículos:

 

Un coche, un patinete y una moto son vehículos, pero desde luego ni un patinete ni una moto tienen “puertas”. El problema es que, al estar ligados dentro de una herencia, debemos indicar de alguna forma que ni a una moto ni a un patinete se le pueden abrir las puertas.

¿Alternativa? Desgranar más la herencia y apoyarnos en interfaces para que quede perfectamente identificadas aquellas partes comunes de las que no lo son. Una posible solución sería la siguiente:

Interface Segregation

Este punto está muy ligado con el apartado anterior. No podemos forzar a los clientes de las interfaces a tener funcionalidades que no implementan. Un ejemplo fácil de entender puede ser la interfaz “IAve”.

 

Es mejor tener más interfaces especializadas:

 

Dependency inversion

Es necesario conseguir un desacoplamiento entre código, de tal forma que, si una clase emplea otras clases, la inicialización de los objetos venga ya inicializada.

¿Claro? ¿Lo intentamos con un ejemplo? Supongamos el siguiente ejemplo:

Supongamos que modificamos el los métodos de la clase “ClaseA” o de la “ClaseB” ¡o peor aún! ¡si se añadiesen parámetros a los constructores!

Al no estar correctamente desacoplados, provocaría muchos cambios, sobre todo si el uso de estas clases es bastante recurrente. La mejor forma es que estas clases dejen de declararse en las funciones y que lleguen sus interfaces por parámetros a los constructores. De esta forma, cuando se vayan a usar, ya deberían venir inicializadas y sería fácil provocar excepciones si no fuese el caso. A continuación, os pongo un ejemplo completo en el que incluyo validaciones a nivel de constructor para cerciorarme de que los parámetros llegan inicializados.