Principios SOLID en JavaScript: teoría y práctica de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Principios SOLID en JavaScript: teoría y práctica de la A a la Z

\n\n

El desarrollo de software de calidad requiere no solo conocer la sintaxis del lenguaje, sino también comprender los principios de arquitectura. SOLID son cinco principios fundamentales del diseño orientado a objetos que ayudan a crear código flexible, mantenible y escalable. En este artículo, analizaremos cada principio SOLID en el contexto de JavaScript (Node.js) con ejemplos prácticos.

\n\n

¿Qué es SOLID?

\n\n

El acrónimo SOLID fue introducido por Robert Martin (Tío Bob) e incluye los siguientes principios:

\n\n
    \n
  • S — Single Responsibility Principle (Principio de responsabilidad única)
  • \n
  • O — Open/Closed Principle (Principio de abierto/cerrado)
  • \n
  • L — Liskov Substitution Principle (Principio de sustitución de Liskov)
  • \n
  • I — Interface Segregation Principle (Principio de segregación de interfaces)
  • \n
  • D — Dependency Inversion Principle (Principio de inversión de dependencias)
  • \n
\n\n

Estos principios son universales y aplicables a cualquier lenguaje de programación, incluido JavaScript. Veamos cada uno de ellos en detalle.

\n\n

1. Single Responsibility Principle (SRP)

\n\n

Definición: Una clase o módulo debe tener solo una razón para cambiar. En otras palabras, cada módulo es responsable de una tarea específica.

\n\n

Ejemplo incorrecto: La clase UserService, que se encarga de guardar el usuario, enviar un email y generar informes.

\n\n
// ❌ Violación de SRP\nclass UserService {\n    saveUser(user) {\n        // Guardar en la base de datos\n        console.log('Usuario guardado');\n    }\n\n    sendEmail(user) {\n        // Enviar email\n        console.log('Email enviado a ' + user.email);\n    }\n\n    generateReport(user) {\n        // Generar informe\n        console.log('Informe generado para ' + user.name);\n    }\n}
\n\n

Ejemplo correcto: Dividimos la responsabilidad en clases separadas.

\n\n
// ✅ Cumplimiento de SRP\nclass UserRepository {\n    save(user) {\n        console.log('Usuario guardado');\n    }\n}\n\nclass EmailService {\n    send(user) {\n        console.log('Email enviado a ' + user.email);\n    }\n}\n\nclass ReportGenerator {\n    generate(user) {\n        console.log('Informe generado para ' + user.name);\n    }\n}\n\n// Uso\nconst user = { name: 'Iván', email: 'ivan@example.com' };\nconst userRepo = new UserRepository();\nconst emailService = new EmailService();\nconst reportGen = new ReportGenerator();\n\nuserRepo.save(user);\nemailService.send(user);\nreportGen.generate(user);
\n\n

Ahora cada clase tiene una única responsabilidad, y los cambios en un módulo no afectan a los demás.

\n\n

2. Open/Closed Principle (OCP)

\n\n

Definición: Las entidades de software (clases, módulos, funciones) deben estar abiertas para la extensión, pero cerradas para la modificación.

\n\n

Ejemplo incorrecto: Una función que calcula el área de figuras usando condicionales.

\n\n
// ❌ Violación de OCP\nfunction calculateArea(shape) {\n    if (shape.type === 'circle') {\n        return Math.PI * shape.radius ** 2;\n    } else if (shape.type === 'rectangle') {\n        return shape.width * shape.height;\n    }\n    // Al agregar una nueva figura, hay que modificar la función\n    return 0;\n}
\n\n

Ejemplo correcto: Usamos polimorfismo y herencia.

\n\n
// ✅ Cumplimiento de OCP\nclass Shape {\n    area() {\n        throw new Error('El método area() debe ser implementado');\n    }\n}\n\nclass Circle extends Shape {\n    constructor(radius) {\n        super();\n        this.radius = radius;\n    }\n\n    area() {\n        return Math.PI * this.radius ** 2;\n    }\n}\n\nclass Rectangle extends Shape {\n    constructor                

Blogs

Book Recommendations