Nota: l'esempio di codice è scritto in c #, ma non dovrebbe importare. Ho messo 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.
Mi trovo spesso a lottare per seguire il principio della responsabilità singola (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 interessa cosa sia Fluffy. Voglio una classe per recuperare le lanugine. Tuttavia, le lanugine possono cambiare secondo una certa logica. A seconda della logica, questa classe restituirà i dati dalla cache o otterrà le ultime dal database. Potremmo dire che gestisce le lanugine, e questa è una cosa. Per semplificare, supponiamo che i dati caricati siano validi per un'ora e quindi debbano 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()
mi sembra ok. L'utente chiede alcuni soffici, li forniamo. Andare a recuperarli dal DB se necessario, ma questo potrebbe essere considerato una parte dell'ottenere le lanugine (ovviamente, è un po 'soggettivo).
NeedsReload()
sembra giusto. Verifica se dobbiamo ricaricare le lanugine. UpdateNextLoad va bene. Aggiorna il tempo per la prossima ricarica. questa è sicuramente una cosa sola.
Tuttavia, sento che cosa LoadFluffies()
non può essere descritto come una sola cosa. Sta ottenendo i dati dal database e sta pianificando il prossimo ricaricamento. È difficile sostenere che il calcolo del tempo per la prossima ricarica faccia parte del recupero dei dati. Tuttavia, non riesco a trovare un modo migliore per farlo (rinominare la funzione LoadFluffiesAndScheduleNextLoad
potrebbe essere migliore, ma rende il problema più ovvio).
Esiste una soluzione elegante per scrivere davvero questa classe secondo l'SRP? Sono troppo pedante?
O forse la mia classe non sta davvero facendo solo una cosa?
DateTime.UtcNow
modo da evitare i cambi di ora legale o persino un cambiamento nel fuso orario corrente.