Nota: l'esempio del codice è scritto in c #, ma non dovrebbe essere importante. Ho inserito C # come tag perché non riesco a trovarne uno più appropriato. Riguarda la struttura del codice.
Sto leggendo Clean Code e sto cercando di diventare un programmatore migliore.
Spesso mi trovo a dover lottare per seguire il Principio di Responsabilità Unica (le classi e le funzioni dovrebbero fare solo una cosa), specialmente nelle funzioni. Forse il mio problema è che "una cosa" non è ben definita, ma comunque ...
Un esempio: ho un elenco di Fluffies in un database. Non ci importa cosa sia un Fluffy. Voglio una classe per recuperare i fluff. Tuttavia, i fluffies possono cambiare secondo una logica. A seconda della logica, questa classe restituirà i dati dalla cache o recupererà l'ultima dal database. Potremmo dire che gestisce i fluff, e questa è una cosa. Per semplificare, supponiamo che i dati caricati siano validi per un'ora, quindi devono essere ricaricati.
class FluffiesManager
{
private Fluffies m_Cache;
private DateTime m_NextReload = DateTime.MinValue;
// ...
public Fluffies GetFluffies()
{
if (NeedsReload())
LoadFluffies();
return m_Cache;
}
private NeedsReload()
{
return (m_NextReload < DateTime.Now);
}
private void LoadFluffies()
{
GetFluffiesFromDb();
UpdateNextLoad();
}
private void UpdateNextLoad()
{
m_NextReload = DatTime.Now + TimeSpan.FromHours(1);
}
// ...
}
GetFluffies()
sembra ok per me. L'utente chiede alcuni fluff, li forniamo. Andando a recuperarli dal DB, se necessario, ma ciò potrebbe essere considerato come una parte dell'ottenere i fluff (ovviamente, è un po 'soggettivo).
NeedsReload()
sembra giusto. Controlla se abbiamo bisogno di ricaricare i fluff.
UpdateNextLoad va bene. Aggiorna il tempo per la prossima ricarica. è sicuramente una cosa sola.
Tuttavia, ritengo che ciò che LoadFluffies()
do non può essere descritto come una singola cosa. Sta ottenendo i dati dal database e sta pianificando il prossimo ricaricamento. È difficile sostenere che il calcolo del tempo per il prossimo ricaricamento è parte dell'ottenere i dati. Tuttavia, non riesco a trovare un modo migliore per farlo (rinominare la funzione in LoadFluffiesAndScheduleNextLoad
potrebbe essere migliore, ma rende solo il problema più ovvio).
Esiste una soluzione elegante per scrivere davvero questa classe in base all'SRP? Sono troppo pedante?
O forse la mia classe non sta facendo proprio una cosa?