La responsabilidad única podría no ser algo que una sola función pueda cumplir.
class Location {
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Esta clase puede romper el principio de responsabilidad única. No porque tenga dos funciones, sino por el código getX()
y getY()
para satisfacer a diferentes partes interesadas que pueden exigir un cambio. Si el Vicepresidente Sr. X envía un memorando de que todos los números se expresarán como números de coma flotante y la Directora de Contabilidad, la Sra. Y insiste en que todos los números que revisa su departamento permanecerán enteros independientemente de lo que el Sr. X piense bien, entonces esta clase debería tener Una sola idea de quién es responsable porque las cosas están a punto de volverse confusas.
Si se hubiera seguido SRP, estaría claro si la clase de ubicación contribuye a las cosas a las que están expuestos el Sr. X y su grupo. Deje en claro de qué es responsable la clase y sepa qué directiva impacta esta clase. Si ambos impactan en esta clase, entonces estaba mal diseñada para minimizar el impacto del cambio. "Una clase solo debe tener una razón para cambiar" no significa que toda la clase solo pueda hacer una pequeña cosa. Significa que no debería poder mirar la clase y decir que tanto el Sr. X como la Sra. Y tienen interés en esta clase.
Aparte de cosas como esas. No, múltiples métodos están bien. Simplemente dele un nombre que aclare qué métodos pertenecen a la clase y cuáles no.
El SRP del tío Bob tiene más que ver con la ley de Conway que con la ley de Curly . El tío Bob aboga por aplicar la Ley de Curly (hacer una cosa) a funciones, no a clases. SRP advierte contra los motivos de mezcla para cambiar juntos. La Ley de Conway dice que el sistema seguirá cómo fluye la información de una organización. Eso lleva a seguir SRP porque no te importa lo que nunca escuchas.
"Un módulo debe ser responsable ante un solo actor"
Robert C Martin - Arquitectura limpia
La gente sigue queriendo que SRP sea sobre todas las razones para limitar el alcance. Hay más razones para limitar el alcance que SRP. Limito aún más el alcance al insistir en que la clase sea una abstracción que puede tomar un nombre que garantice que mirar dentro no te sorprenda .
Puedes aplicar la Ley de Curly a las clases. Estás fuera de lo que habla el tío Bob, pero puedes hacerlo. Cuando te equivocas es cuando comienzas a pensar que eso significa una función. Es como pensar que una familia solo debe tener un hijo. Tener más de un hijo no impide que sea una familia.
Si aplica la ley de Curly a una clase, todo en la clase debe tratarse de una sola idea unificadora. Esa idea puede ser amplia. La idea podría ser la persistencia. Si algunas funciones de utilidad de registro están allí, entonces están claramente fuera de lugar. No importa si el Sr. X es el único a quien le importa este código.
El principio clásico para aplicar aquí se llama Separación de preocupaciones . Si separa todas sus preocupaciones, se podría argumentar que lo que queda en cualquier lugar es una preocupación. Así llamamos a esta idea antes de que la película de 1991 City Slickers nos presentara al personaje Curly.
Esto esta bien. Es solo que lo que el tío Bob llama responsabilidad no es una preocupación. Una responsabilidad hacia él no es algo en lo que te concentres. Es algo que puede obligarte a cambiar. Puede concentrarse en una preocupación y aún así crear código que sea responsable ante diferentes grupos de personas con diferentes agendas.
Tal vez no te importe eso. Multa. Pensar que sostener "hacer una cosa" resolverá todos sus problemas de diseño muestra una falta de imaginación de lo que "una cosa" puede llegar a ser. Otra razón para limitar el alcance es la organización. Puede anidar muchas "una cosa" dentro de otras "una cosa" hasta que tenga un cajón de basura lleno de todo. He hablado de eso antes
Por supuesto, la razón clásica de OOP para limitar el alcance es que la clase tiene campos privados y, en lugar de usar getters para compartir esos datos, colocamos todos los métodos que necesitan esos datos en la clase donde pueden usar los datos en privado. Muchos consideran que esto es demasiado restrictivo para usarlo como limitador de alcance porque no todos los métodos que pertenecen juntos usan exactamente los mismos campos. Me gusta asegurarme de que cualquier idea que reunió los datos sea la misma idea que unió los métodos.
La forma funcional de ver esto es eso a.f(x)
y a.g(x)
son simplemente f a (x) y g a (x). No dos funciones, sino un continuo de pares de funciones que varían juntas. El a
ni siquiera tiene que tener los datos en ella. Podría ser simplemente cómo sabes qué implementación f
y g
qué vas a usar. Las funciones que cambian juntas pertenecen juntas. Eso es buen viejo polimorfismo.
SRP es solo una de las muchas razones para limitar el alcance. Es una buena. Pero no el único.