🧩 Single Responsibility Principle (SRP) - Principio de Responsabilidad Única.
¿Qué es?
El Single Responsability Principle es uno de los cinco principios SOLID de la programación orientada a objetos. Este principio dice que una clase debe tener una única responsabilidad y por lo tanto solo una razón para cambiar.
Esto entre otras cosas, facilita:
- La reutilización del código.
- Facilidad para testear.
- Código más sencillo de entender y mantener.
Ejemplo.
Imagina que trabajas en una tienda muy grande como un empleado polifacético. Haces de todo: repones productos en las estanterías, atiendes a los clientes, cobras en la caja, revisas el stock, haces pedidos, cuadras las cuentas, contactas con distribuidores etc.
Es bastante probable que exista un empleado con todas estas tareas, quizá en tiendas pequeñas, pero en una tienda grande la tendencia es distribuir las tareas para ganar eficiencia y organización. Por ejemplo:
- Cajero/a.
- Reponedor/a.
- Vendedor/a.
Repartir las tareas de esta forma también hace que las personas cometan menos fallos, porque se especializan en sus tareas y las hacen bien.
En la programación pasa algo similar. Si tienes una clase que hace de todo, como tu rol en la tienda, al final se vuelve un punto de fallo único y puede llegar a ser un auténtico caos.
Si algo va mal o hay que cambiar algo, todo el sistema se ve afectado y vulnerable a posibles fallos. Corregir un pequeño problema puede volverse complicado y costoso.
Por eso tu clase SuperDependiente no debería poder implementar los métodos Atender, Reponer y Cobrar, CuadrarCuentas, RevisarStock… quedaría algo así:
class SuperDependiente {
public function atenderCliente() { /* ... */ }
public function reponerProductos() { /* ... */ }
public function cobrar() { /* ... */ }
public function revisarStock() { /* ... */ }
public function hacerPedidos() { /* ... */ }
public function cuadrarCuentas() { /* ... */ }
}
$empleadoEjemplar = new SuperDependiente();
Refactor.
Si refactorizamos para cumplir el SRP quedaría algo así:
class Vendedor {
public function atenderCliente() { /* ... */ }
}
class Reponedor {
public function reponerProductos() { /* ... */ }
}
class Cajero {
public function cobrar() { /* ... */ }
}
class GestorInventario {
public function hacerPedidos() { /* ... */ }
}
Con este refactor ganamos:
- Mantenibilidad: Es más fácil mantener clases con una sola responsabilidad.
- Legibilidad: Código más fácil de entender.
- Testabilidad: Código más fácil de testear.
¿Cómo lo detectamos?
- Por el nombre: Nombres con “And”, “Or” o múltiples verbos (
validateAndProcess) se delatan solos - Clases grandes: Muchos métodos (>10-15) pueden indicar múltiples responsabilidades
- Muchas dependencias: Si inyectas 5+ dependencias, posiblemente hace demasiado
- Difícil testeo: Si necesitas mockear muchas cosas para un test
- Cambios frecuentes: Si tocas la clase por razones muy diferentes
espero que se haya entendido jejejeje ¡ea nos vemos! 🍻