Principio de Responsabilidad Única (SRP)
Introducción
El Principio de Responsabilidad Única (SRP, por sus siglas en inglés) es uno de los pilares de los Principios SOLID en el desarrollo de software. Este principio establece que una clase o módulo debe tener una sola razón para cambiar, es decir, debe encargarse de una única responsabilidad. En aplicaciones desarrolladas con Express.js, aplicar SRP no solo mejora la mantenibilidad y escalabilidad del código, sino que también facilita el trabajo en equipo.
En este artículo, exploraremos cómo aplicar el SRP en proyectos Express utilizando buenas prácticas y ejemplos prácticos.
¿Qué es el Principio de Responsabilidad Única?
El SRP dicta que cada módulo o componente de una aplicación debe ser responsable de una sola funcionalidad o tarea. Esto significa que:
- Cada archivo o función debe enfocarse en una responsabilidad específica.
- Los cambios en una parte del sistema no deben afectar a otras partes de manera innecesaria.
¿Por Qué Aplicar SRP en Express?
En aplicaciones Express, es común ver que las rutas, controladores, y lógica de negocio se mezclen en un solo archivo, lo que genera código difícil de mantener. Aplicar SRP ofrece ventajas como:
- Código más legible y organizado.
- Facilidad para realizar pruebas unitarias.
- Mayor escalabilidad.
- Reducción del riesgo de errores.
Buenas Prácticas para Aplicar SRP en Express
Separar Rutas, Controladores y Lógica de Negocio
Una práctica común es dividir el proyecto en diferentes capas o módulos:
- Rutas: Define los endpoints y las solicitudes HTTP.
- Controladores: Procesan las solicitudes y gestionan las respuestas.
- Servicios: Contienen la lógica de negocio.
- Modelos: Gestionan la interacción con la base de datos.
Ejemplo Práctico: Aplicando SRP en Express
Estructura del Proyecto
src/
│
├── routes/
│ └── usuarios.routes.js
│
├── controllers/
│ └── usuarios.controller.js
│
├── services/
│ └── usuarios.service.js
│
└── app.js
Archivo usuarios.routes.js
Define los endpoints y asigna cada uno a un controlador específico.
const express = require('express');
const router = express.Router();
const { obtenerUsuarios, crearUsuario } = require('../controllers/usuarios.controller');
router.get('/', obtenerUsuarios);
router.post('/', crearUsuario);
module.exports = router;
Archivo usuarios.controller.js
Separa la lógica de las rutas y delega responsabilidades al servicio.
const { listarUsuarios, agregarUsuario } = require('../services/usuarios.service');
const obtenerUsuarios = async (req, res) => {
try {
const usuarios = await listarUsuarios();
res.status(200).json(usuarios);
} catch (error) {
res.status(500).json({ mensaje: 'Error al obtener usuarios', error });
}
};
const crearUsuario = async (req, res) => {
try {
const nuevoUsuario = await agregarUsuario(req.body);
res.status(201).json(nuevoUsuario);
} catch (error) {
res.status(500).json({ mensaje: 'Error al crear usuario', error });
}
};
module.exports = { obtenerUsuarios, crearUsuario };
Archivo usuarios.service.js
Centraliza la lógica de negocio.
const usuariosDB = []; // Simulación de una base de datos en memoria
const listarUsuarios = async () => {
return usuariosDB;
};
const agregarUsuario = async (usuario) => {
const nuevoUsuario = { id: usuariosDB.length + 1, ...usuario };
usuariosDB.push(nuevoUsuario);
return nuevoUsuario;
};
module.exports = { listarUsuarios, agregarUsuario };
Archivo app.js
Carga las rutas en la aplicación.
const express = require('express');
const app = express();
const usuariosRoutes = require('./routes/usuarios.routes');
app.use(express.json());
app.use('/usuarios', usuariosRoutes);
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Servidor ejecutándose en http://localhost:${PORT}`);
});
Caso de Uso: Creación de una API REST para Gestión de Usuarios
Sin SRP:
Todo el código estaría en un único archivo, dificultando el mantenimiento y el trabajo colaborativo.Con SRP:
La separación en módulos permite que diferentes desarrolladores trabajen en rutas, controladores o servicios de forma independiente. Además, facilita la escalabilidad de la aplicación, por ejemplo, al agregar autenticación o validaciones.
Beneficios de Aplicar SRP en Express
- Mantenibilidad: El código dividido en responsabilidades claras es más fácil de entender y actualizar.
- Pruebas Unitarias: Es sencillo probar los servicios o controladores de manera aislada.
- Escalabilidad: Agregar nuevas funcionalidades no implica modificar grandes secciones del código existente.
- Colaboración: Los equipos pueden trabajar en diferentes partes de la aplicación sin conflictos.
Conclusión
El Principio de Responsabilidad Única es esencial para crear aplicaciones Express robustas y escalables. Separar rutas, controladores, y lógica de negocio no solo organiza mejor tu proyecto, sino que también reduce el tiempo de desarrollo y mantenimiento. Si trabajas en equipo o desarrollas proyectos a largo plazo, aplicar SRP es una inversión que vale la pena.
Links de referencia: