Principios SOLID: Aplicación Práctica en Arquitecturas Limpias

Clase 5 de 24Curso de Arquitecturas Limpias para Desarrollo de Software

Resumen

¿Qué son los principios de diseño SOLID?

Los principios de diseño SOLID son una serie de normas que guían a los desarrolladores en la creación de software más mantenible, flexible y escalable. Estos principios son esenciales para implementar arquitecturas limpias. Aunque son cinco en total, en esta ocasión nos enfocaremos en tres: el principio de responsabilidad única (S), el principio de abierto y cerrado (O) y el principio de inversión de dependencias (D).

¿Qué es el principio de responsabilidad única?

El principio de responsabilidad única, representado por la letra "S" en SOLID, afirma que un módulo debe tener una sola razón para cambiar. Un módulo puede ser un archivo o una clase, y este principio nos ayuda a evitar combinar múltiples responsabilidades en un solo lugar.

Ejemplo práctico:

Imagina una aplicación en JavaScript que recibe solicitudes a través del método POST, realiza validaciones y guarda datos en una base de datos. Actualmente, este código tiene tres razones para cambiar: la comunicación (HTTP), la validación de datos y el acceso a la base de datos.

function handleRequest(req) {
  validateRequest(req);
  saveToDatabase(req);
}

function validateRequest(req) {
  // Validaciones para correo y nombre
}

function saveToDatabase(req) {
  // Inserta en la base de datos
}

En lugar de combinar estas tareas, el principio de responsabilidad única sugiere que debemos separarlas en funciones o clases, cada una con su propia responsabilidad.

¿Cómo aplicar el principio de abierto y cerrado?

El principio de abierto y cerrado, simbolizado por la letra "O", sugiere que un módulo debe estar abierto para extenderse pero cerrado para modificarse. Esto implica que, en lugar de alterar el código existente al añadir nuevas funcionalidades, las nuevas características deben integrarse sin modificar la estructura ya existente.

Ejemplo práctico:

En un sistema con estructuras condicionales encadenadas para diferentes ciudades:

if (city === 'Cali') {
  processCali();
} else if (city === 'Lima') {
  processLima();
}

Es preferible estructurarlo para permitir extensibilidad:

class CityProcessor {
  process() {}
}

class CaliProcessor extends CityProcessor {
  process() {
    // Proceso para Cali
  }
}

class LimaProcessor extends CityProcessor {
  process() {
    // Proceso para Lima
  }
}

Al crear clases específicas, podemos añadir nuevas ciudades aplicando herencia, evitando modificar el código existente y mejorando la mantenibilidad.

¿Qué es el principio de inversión de dependencias?

El principio de inversión de dependencias, correspondiente a la letra "D", sostiene que los módulos de alto nivel no deben depender de los módulos de bajo nivel. Más bien, ambos deben depender de abstracciones, ya que los detalles deben depender de las abstracciones y no al revés.

Explicación detallada:

  • Presentación y Acceso a Datos: Son módulos de bajo nivel. Tienden a cambiar más frecuentemente.
  • Dominio (Lógica de Negocio): Es un módulo de alto nivel. Debe permanecer independiente de detalles de implementación específicos, como cambios en la base de datos o en la interfaz de usuario.

Uso de la inyección de dependencias:

La inyección de dependencias es crucial para implementar este principio, ya que permite que los módulos de alto nivel no dependan directamente de las implementaciones de bajo nivel, sino de interfaces o abstracciones.

Mediante estos principios, los desarrolladores pueden lograr sistemas más robustos, con un crecimiento controlado y sostenibles en el tiempo, comenzando por una estructura robusta y lógica desde el inicio de los proyectos. ¡Continúa explorando estos conceptos para perfeccionar aún más tus habilidades de programación!