El principio de responsabilidad única ( SRP ) es un principio OOP que significa que cada objeto debe tener una responsabilidad y esta responsabilidad debe estar completamente encapsulada en una clase . Toda su conducta debe estar dirigida únicamente a asegurar esta responsabilidad.
Una clase debe tener una sola razón para cambiar.Roberto C. Martín
El término SRP fue acuñado por Robert S. Martin en un artículo del mismo nombre como parte de SOLID , popularizado por su libro Rapid Software Development. Principios, ejemplos, práctica.” [1] . Martin describió SRP basándose en un patrón descrito por Tom DeMarco [2] y Mailer Page-Jones [3] llamado conectividad .
En SOLID , la letra "S" es una abreviatura del principio de responsabilidad única.
Martin define la responsabilidad como la razón del cambio y concluye que las clases deben tener una y sólo una razón para el cambio. Por ejemplo, imagine una clase que escribe e imprime un informe. Tal clase puede cambiar por dos razones:
Lógicamente, ambos aspectos de estas causas son en realidad dos responsabilidades diferentes. SRP dice que en este caso, debe dividir la clase en dos clases nuevas, que se caracterizarán por una sola responsabilidad. La razón por la que es importante mantener las clases enfocadas en un solo propósito es porque hace que las clases sean más saludables. En cuanto a la clase anterior, si hubo un cambio en el proceso de compilación del informe, existe una alta probabilidad de que el código responsable de la impresión quede inutilizable.
Al diseñar diferentes comportamientos para una misma clase, a menudo aparece un " Objeto de Dios ", que se considera un anti -patrón en OOP . Seguir el principio de responsabilidad única evita este antipatrón.
Surge la pregunta ¿cuándo vale la pena usar este principio? Aún así, un principio no es una ley y SRP debe aplicarse dependiendo de cómo cambie la aplicación:
Seguir ciegamente el principio de responsabilidad única conduce a una complejidad excesiva de la aplicación, su soporte y pruebas. SRP solo debe usarse cuando esté justificado. El principio SRP solo se puede aplicar cuando:
La consolidación de responsabilidades es una práctica común y no tiene nada de malo, siempre que sea fácil de mantener. Seguir el principio de responsabilidad única depende de las funciones del producto de software y es lo más difícil cuando se diseñan aplicaciones.
ActiveRecord se cita a menudo como un ejemplo de violaciones de SRP , un patrón que le permite vincular fácilmente datos de objetos y datos de una base de datos. En ActiveRecord, muchas responsabilidades se concentran en un solo lugar y, por lo tanto, se puede argumentar que ActiveRecord viola el SRP y, por lo tanto, se convierte en un antipatrón. [4] En algunos casos, esta afirmación es discutible, ya que el objeto en sí, que implementa ActiveRecord, no contiene ninguna lógica comercial, pero proporciona una tabla de la base de datos, tiene una sola razón para cambiar (cambiar la tabla), que no no contradiga la definición del principio SRP [5] [6] .
Las siguientes técnicas le permiten cumplir con el principio de responsabilidad única:
Un ejemplo clásico [7] de una violación de SRP es cuando un sistema de reglas de negocios ( BRMS ) necesita lidiar con almacenamiento persistente ( Persistencia ). En las primeras etapas del diseño de dichos sistemas, se crea una clase que procesa las reglas comerciales y contiene la lógica para trabajar con la base de datos. Con la violación del SRP aparecen signos de un mal proyecto , tales como:
Si el sistema se desarrolló originalmente a través de pruebas ( TDD ), es posible que este problema no se haya presentado. Según las pruebas, los desarrolladores pueden imaginar rápidamente qué funcionalidad necesita el usuario. Así, los detalles de la clase aparecen mucho antes de la implementación final de la solución, influyendo así en el diseño del sistema desarrollado. Pero también sucede que el desarrollo basado en pruebas no conduce a la aplicación del patrón Class Extraction , entonces el sistema se refactoriza usando los patrones Facade , DAO o Proxy .
SRP sugiere separar las clases genéricas en clases concretas, lo que las hará simples y fáciles de mantener. El principio KISS también propone una idea similar [8] .