Como sabemos, el SRP establece que cada clase debe tener una responsabilidad única y que la responsabilidad debe estar totalmente encapsulada por la clase.
Pero los establecedores y captadores tienen otra responsabilidad : hacen un acceso de propiedad de clase abstracta (datos).
si los Setters y getters tienen acceso a la propiedad de clase abstracta, entonces tienen otra responsabilidad .
Entonces, si tengo algo como esto,
class Config
{
private location;
public function write(array $data)
{
....
}
public function read($key)
{
...
}
public function exists($key)
{
...
}
public function delete($key)
{
...
}
// Below comes property abstraction
// Here I doubt - I CANNOT USE this class without them
// but they seem to break the SRP at the same time!?
public function setFileLocation($location)
{
$this->location = $location;
}
public function getFileLocation()
{
return $this->location;
}
public function setConfigArray(...)
{
...
}
public function getConfigArray()
{
...
}
}
Rompo el SRP. El problema es que esa es la única forma en que la clase puede existir.
Entonces la pregunta es,
En mi situación, es casi imposible de evitar setFileLocation()
y los getFileLocation()
métodos con CRUD.
Entonces, si combinando métodos CRUD con abstracción de acceso a datos, rompo el SRP,
¿Hay alguna forma de adherir el SRP y mantener el concepto común de la clase Config (operaciones CRUD) al mismo tiempo?
Respuestas:
Honestamente, creo que estás llevando el concepto de responsabilidad individual un poco demasiado lejos. Los captadores y establecedores son incidentales para el funcionamiento de la clase, ya sea que lo haga por acceso directo a miembros públicos o use métodos (o propiedades) para hacerlo.
Está argumentando que obtener y establecer a algún miembro de la clase es una responsabilidad separada y, por lo tanto, debe trasladarse a otro lugar. Digamos que hacemos eso, y ahora tienes clases llamadas
Config
yConfigAccessor
. En este punto, ahora tiene un espacio de aire entre las dos clases, porqueConfig
no tiene una interfaz para acceder a sulocation
miembro. Eso hace que sea imposible escribirConfigAccessor
, y te queda una clase inmutable de escritura única que no sirve de nada. Si agrega algún tipo de interfaz para permitirConfigAccessor
hacer su trabajo, se encontrará con un problema recurrente.El SRP, como muchas otras cosas en este campo, es un principio, no una regla estricta. Eso significa que debe aplicar el juicio a su situación en lugar de tratar de seguirla incondicionalmente. Hay una línea entre ser un purista y hacer el trabajo, y cuando el primero está impidiendo al segundo, estás en el lado equivocado.
Si puedo criticar un poco su diseño: si su
Config
clase está diseñada para ser una interfaz entre un archivo de configuración almacenado en el disco y su código, lo último que desea hacer es cambiar su ubicación a mitad de camino. Si está cambiando lalocation
forma de iniciar el acceso a un archivo diferente, debería destruir el objeto antiguo y crear uno nuevo. No dejó en claro si tiene la intención de almacenar el contenido del archivo en el objeto. Si había planeado usarlo como una forma de inhalar el contenido de un archivo de configuración y escribirlo en otro, considere usar un método que clone los datos en un nuevo objeto que apunte al nuevo archivo.fuente
Hay dos niveles distintos en los que puede aplicar el SRP.
El primer nivel es el nivel de funciones / métodos individuales. Cada uno debe hacer solo una tarea (y a juzgar por los nombres de los métodos, ninguno de los métodos de
Config
romper el SRP).El segundo nivel es el nivel de una clase. Aquí, el concepto de una sola responsabilidad se vuelve un poco más abstracto, pero un buen indicador es si puede establecer las responsabilidades de una clase en una oración sin el uso (implícito) de la palabra y . Si puede hacerlo con la presencia de los captadores y establecedores, entonces la clase no rompe el SRP.
En general, los captadores y, en menor medida, los establecedores son , sin embargo, una indicación de que la encapsulación de una clase está rota. En el caso de la
Config
clase, elsetFileLocation
método es bueno, ya queConfig
necesita alguna forma de saber dónde se encuentran los datos, pero los demás parecen sospechosos, porque exponen información que los usuariosConfig
no deberían necesitar.fuente
Su clase de configuración tiene la responsabilidad de rastrear la configuración, que se implementa manteniendo referencias privadas a ciertos datos y proporcionándoles acceso a través de métodos mutadores. Esto no rompe el SRP, porque la clase misma todavía tiene una responsabilidad única ; los mutadores simplemente lo ayudan a cumplir esa responsabilidad abstrayendo el acceso a los datos. Los mutadores no tienen una responsabilidad separada de la de la clase; son parte de la mayor responsabilidad de la clase.
fuente