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.
Filelibreria di C # è che, per quanto ne sappiamo, la Fileclasse 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. :)