Principios SOLID - Single Responsibility Principle (SRP)

Una clase, una responsabilidad. Mejora la claridad y mantenibilidad del código.

Escrito por domin el 11/08/2024

Single Responsibility Principle (SRP) - Principio de Responsabilidad Única.

¿Qué es?

El SRP es uno de los cinco principios SOLID de la programación orientada a objetos. Este principio dice que una clase de tener una responsabilidad y por lo tanto una razón para cambiar. Esto entre otras cosas, facilita:

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 estas tareas, quizá en tiendas pequeñas, pero en una tienda grande se tiende a distribuir las tareas para ganar eficiencia y organización. Por ejemplo:

Repartir las tareas de esta forma también hace que las personas cometan menos fallos.

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:

¿Cómo lo detectamos?