I setter e i getter interrompono sempre il Principio di Responsabilità Unica?

8

Come sappiamo, l'SRP afferma che ogni classe dovrebbe avere un'unica responsabilità e che la responsabilità deve essere interamente incapsulata dal classe.

Ma setters e getter hanno un'altra responsabilità - fanno un accesso astratto alla proprietà di classe (dati).

se Setter e getters fanno un accesso astratto alle proprietà di classe, allora hanno un'altra responsabilità .

Quindi se ho qualcosa di simile,

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()
    {
        ...
    }
}

Rompere l'SRP. Il problema è che, questo è l'unico modo in cui la classe può esistere.

Quindi la domanda è,

Nella mia situazione, è quasi impossibile evitare i metodi setFileLocation() e getFileLocation() con quelli CRUD.

Quindi, se combinando i metodi CRUD con l'astrazione dell'accesso ai dati, interrompo l'SRP,

C'è un modo in cui posso aderire all'SRP e mantenere il concetto comune della classe Config (operazioni CRUD) allo stesso tempo?

    
posta Yang 24.04.2013 - 15:17
fonte

3 risposte

10

Onestamente, penso che tu stia prendendo un po 'troppo in considerazione il concetto di responsabilità unica. Getter e setter sono incidentali al funzionamento della classe, sia che tu lo faccia per accesso diretto ai membri pubblici o usi metodi (o proprietà) per farlo.

Stai facendo la discussione che ottenere e impostare un membro della classe è una responsabilità separata e dovrebbe quindi essere spostato altrove. Diciamo che lo facciamo, e ora hai classi chiamate Config e ConfigAccessor . A questo punto, ora c'è un vuoto d'aria tra le due classi, perché Config non ha un'interfaccia per accedere al suo membro location . Ciò rende impossibile scrivere ConfigAccessor , e ti rimane una classe immutabile, in scrittura una sola volta, che è assolutamente inutile. Se aggiungi una sorta di interfaccia per consentire a ConfigAccessor di eseguire il proprio lavoro, ti troverai con un problema ricorsivo.

L'SRP, come molte altre cose in questo campo, è un principio, non una regola dura e veloce. Ciò significa che dovresti applicare un giudizio alla tua situazione invece di cercare di seguirla incondizionatamente. C'è un confine tra l'essere puristi e il lavoro svolto, e quando il primo impedisce il secondo, sei dalla parte sbagliata.

Se posso criticare un po 'il tuo design: se la tua classe Config è progettata per essere un'interfaccia tra un file di configurazione memorizzato su disco e il tuo codice, l'ultima cosa che vuoi fare è cambiare la sua posizione a metà strada. Se stai modificando location come metodo per iniziare l'accesso a un file diverso, dovresti distruggere il vecchio oggetto e crearne uno nuovo. Non hai chiarito se intendi memorizzare il contenuto del file nell'oggetto. Se avessi intenzione di usarlo come un modo per inalare il contenuto di un file di configurazione e scriverlo su un altro, considera l'utilizzo di un metodo che clona i dati in un nuovo oggetto che punta al nuovo file.

    
risposta data 24.04.2013 - 16:32
fonte
4

Ci sono due livelli distinti ai quali puoi applicare l'SRP.

Il primo livello è il livello delle singole funzioni / metodi. Ognuno dovrebbe fare solo un compito (e a giudicare dai nomi dei metodi, nessuno dei metodi di Config interrompe l'SRP).

Il secondo livello è il livello di una classe. Qui il concetto di una singola responsabilità diventa un po 'più astratto, ma un buon indicatore è se puoi indicare le responsabilità di una classe in una frase senza l'uso (implicito) della parola e . Se puoi farlo con la presenza di getter e setter, allora la classe non infrange lo SRP.

In generale, i getter e, in misura minore, i setter sono , tuttavia, un'indicazione che l'incapsulamento di una classe è rotto. Nel caso della classe Config , il metodo setFileLocation è buono, poiché Config ha bisogno di un modo per sapere dove si trovano i dati, ma gli altri sembrano sospetti, perché espongono le informazioni che gli utenti di Config non dovrebbe averne bisogno.

    
risposta data 24.04.2013 - 16:25
fonte
4

La tua classe di configurazione ha la responsabilità di tracciare la configurazione, che è implementare tenendo i riferimenti privati a determinati dati e fornendo l'accesso ad essi tramite metodi mutator. Questo non infrange l'SRP, perché la classe stessa ha ancora una singola responsabilità ; i mutatori semplicemente aiutano a raggiungere tale responsabilità estraendo l'accesso ai dati. I mutatori non hanno una responsabilità separata da quella della classe; fanno parte della maggiore responsabilità della classe.

    
risposta data 24.04.2013 - 16:20
fonte

Leggi altre domande sui tag