El Principio de Responsabilidad Única

El Principio de Responsabilidad Única
Autor: Uncle Bob

Uno de los principios fundamentales de un buen diseño es: reúna las cosas que cambian por la misma razón y separe aquellas cosas que cambian por diferentes razones.

Este principio es conocido también como el Principio de la Responsabilidad Única o SRP (por sus siglas en inglés). En definitiva, se dice que un subsistema, módulo, clase o incluso una función no debe tener más de una razón para cambiar. El ejemplo clásico es una clase que tiene métodos relacionados con reglas de negocio, reportes y base de datos:

public class Empleado {
  public Money calculaPago() ...
  public String reportaHoras() ...
  public void guardar() ...
}

Algunos programadores podrían pensar que poner estas tres funciones en la misma clase es perfectamente apropiado. Después de todo, se supone que las clases son colecciones de funciones que operan sobre las variables comunes. Sin embargo, el problema es que las tres funciones cambian por razones totalmente distintas. La función calculaPago cambiará cada vez que las reglas de negocio para calcular el pago cambien. La función reportaHoras cambiará cada vez que alguien quiera otro formato para el informe. La función guardar cambiará cada vez que los DBA cambien el esquema de base de datos. Estas tres razones de cambio se combinan para hacer a Empleado muy volátil. Cambiará por alguna de estas razones. Más importante aún, las clase que depende de Empleado será afectadas por estos cambios.

El buen diseño de sistemas significa que separamos el sistema en componentes que pueden ser implementados de forma independientemente. La implementación independiente significa que si cambiamos un componente no tenemos que volver a implementar alguno de los otros. Sin embargo, si Empleadoes muy utilizado por muchas otras clases en otros componentes, entonces es probable que cada cambio a Empleado cause que los otros componentes tengan que volverse a implementar; negando así el mayor beneficio del diseño de componentes (o SOA, si se prefiere un nombre más de moda).

public class Empleado {
  public Money calculaPago() ...
}

public class ReporteadorEmpleado {
  public String reportHora(Empleado e) ...
}

public class RepositorioEmpleado {
  public void guardar(Empleado e) ...
}

La simple división mostrada arriba resuelve estos problemas. Cada una de estas clases se puede colocar en un componente para sí mismas. O, mejor dicho, todos las clases de reporteo pueden ir en el componente de reporteo. Todas las clases relacionadas con base de datos pueden estar en el componente de repositorios. Y todas las reglas de negocios pueden entrar en el componente de reglas de negocio.

El lector astuto verá que aún existen dependencias en la solución anterior. Ese Empleado aún depende de las otras clases. Si se modificaEmpleado, es probable que las otras clases se tengan que volver a compilar e implementar. Por lo tanto Empleado no se puede modificar y después implementar independientemente. Sin embargo, las otras clases pueden ser modificadas e implementadas independientemente. Ninguna modificación de alguna clase puede forzar a cualquiera de los otras a ser recompiladas o reimplementadas. Incluso Empleado podría ser implementada independientemente a través de un uso cuidadoso del Principio de Inversión de Dependencias (DIP), pero eso es un tema para otro libro.

La aplicación cuidadosa del SRP, separando las cosas que cambian por diferentes razones, es una de las claves para la creación de diseños que tienen una estructura de componentes de implementación independientemente.

Leer contribución original

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *