Scrivo un sacco di codice che prevede tre passaggi di base.
- Ottieni dati da qualche parte.
- Trasforma quei dati.
- Metti quei dati da qualche parte.
In genere finisco per usare tre tipi di lezioni, ispirate ai rispettivi modelli di progettazione.
- Fabbriche - per costruire un oggetto da una risorsa.
- Mediatori: per usare la fabbrica, eseguire la trasformazione, quindi usare il comandante.
- Comandanti - per mettere quei dati altrove.
Le mie lezioni tendono a essere piuttosto piccole, spesso un singolo metodo (pubblico), ad esempio ottenere dati, trasformare dati, lavorare, salvare dati. Questo porta a una proliferazione di classi, ma in generale funziona bene.
Il punto in cui faccio fatica quando vengo ai test, finirò per fare test strettamente collegati. Per esempio;
- Factory: legge i file dal disco.
- Commander: scrive i file sul disco.
Non posso testarne uno senza l'altro. Potrei scrivere un ulteriore codice 'test' per fare anche la lettura / scrittura del disco, ma poi mi sto ripetendo.
Guardando .Net, la classe File adotta un approccio diverso, combina le responsabilità (della mia) fabbrica e comandante insieme. Ha funzioni per Crea, Elimina, Esiste e Leggi tutto in un unico posto.
Dovrei cercare di seguire l'esempio di .Net e combinare, in particolare quando si tratta di risorse esterne, le mie lezioni insieme? Il codice è ancora accoppiato, ma è più intenzionale: succede nell'implementazione originale, piuttosto che nei test.
Il mio problema qui è che ho applicato il principio della responsabilità singola in modo un po 'troppo zelante? Ho classi separate responsabili di lettura e scrittura. Quando potrei avere una classe combinata che è responsabile della gestione di una particolare risorsa, ad esempio il disco di sistema.
Looking at .Net, the File class takes a different approach, it combines the responsibilities (of my) factory and commander together. It has functions for Create, Delete, Exists, and Read all in one place.
- Nota che stai unendo "responsabilità" con "cosa da fare". Una responsabilità è più simile a una "area di interesse". La responsabilità della classe File sta eseguendo operazioni sui file.
File
libreria di C # è che, per quanto ne sappiamo, la File
classe potrebbe essere solo una facciata, mettendo tutte le operazioni sui file in un unico posto - nella classe, ma potrebbe essere internamente utilizzare una classe di lettura / scrittura simile alla tua che in realtà contiene la logica più complicata per la gestione dei file. Tale classe (la File
) aderirebbe comunque all'SRP, perché il processo di funzionamento effettivo con il filesystem verrebbe astratto dietro un altro livello, molto probabilmente con un'interfaccia unificante. Non dire che è il caso, ma potrebbe essere. :)