¿Los establecedores y captadores siempre rompen el principio de responsabilidad única?

8

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?

Yang
fuente
1
@metal_fan: Rompe exactamente la misma funcionalidad si tiene un miembro público o si tiene un miembro privado con getter y setter público trivial. Y digo exactamente lo mismo porque puede no ser ninguno en algunos casos y todo en otros. Dependiendo de si usarlos puede romper invariantes internos.
Jan Hudec
1
¿Cuál es la responsabilidad de la clase config si no es proporcionar un lugar centralizado para almacenar y recuperar esos valores de configuración? ¿SRP está roto en cada base de datos? En el ejemplo que enlace hay dos responsabilidades, 1 es getters y setters, 2 es CRUD. En el ejemplo que publica, no hay CRUD, por lo que solo hay 1 responsabilidad.
Trylks
" Has confundido lo verdadero y lo real " - George Stanley en conversación, citado por Samuel R Delany

Respuestas:

11

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 Configy ConfigAccessor. En este punto, ahora tiene un espacio de aire entre las dos clases, porque Configno tiene una interfaz para acceder a su locationmiembro. Eso hace que sea imposible escribir ConfigAccessor, y te queda una clase inmutable de escritura única que no sirve de nada. Si agrega algún tipo de interfaz para permitir ConfigAccessorhacer 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 Configclase 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 la locationforma 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.

Blrfl
fuente
4

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 Configromper 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 Configclase, el setFileLocationmétodo es bueno, ya que Confignecesita alguna forma de saber dónde se encuentran los datos, pero los demás parecen sospechosos, porque exponen información que los usuarios Configno deberían necesitar.

Bart van Ingen Schenau
fuente
4

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.

Mike Partridge
fuente