Attualmente sto refactoring di un'applicazione che scarica periodicamente il contenuto da varie fonti (http, ftp, sql, ecc.). Esiste una pianificazione che controlla i tempi durante i quali l'applicazione può essere attiva. Ad esempio, può scaricare contenuti tra 8AM e 16PM. L'applicazione è stata scritta in un linguaggio orientato agli oggetti (C #).
Questo è il disegno generale che ho trovato nella mia prima iterazione:
LaclasseSchedulersaràresponsabiledelrispettodelprogrammagenerale.Iniziaildownloadall'iniziodelperiodopianificatoelointerrompeallafine.LoSchedulercontieneunaseriediimplementazioniITask,ognunadellequalihailpropriobitdidownloaddafare.Hocreatoun'implementazioneastrattadellaclassebasecheperiodicamentechiamailmetodoastrattoprotetto"StartDownload". Sottoclassi di attività implementeranno solo questo metodo e non dovranno preoccuparsi dei tempi e della pianificazione.
Finora, tutto bene. Ma durante la base di partenza di TDD'ing the Task, mi sono reso conto che in realtà era difficile prendere in giro il comportamento di StartDownload. Quando il timer del Task esegue un tick, dovrebbe chiamare StartDownload solo se ha terminato la precedente iterazione di download. Ma dal momento che questi sono dettagli di implementazione, è difficile prendere in giro.
Questo mi ha fatto chiedere se la classe Task non stia effettivamente violando il Principio di Responsabilità Unica. Dopo tutto, si sta prendendo cura dell'invocazione periodica di StartDownload. E il metodo StartDownload è responsabile del download effettivo. Così ho trovato un design più separato:
Qui la responsabilità della classe Task è limitata alla sola chiamata periodica del Cliente. E l'unica responsabilità del Cliente è il download di contenuti. Testare la classe Task ora sarà più semplice, perché posso semplicemente inserire un mock IDownloadClient. L'attività e il download hanno una relazione 1 a 1. Quindi ogni attività esegue un download, per così dire. In pratica, tutte le istanze dell'attività verranno aggiunte a una singola istanza dello scheduler e avviate / arrestate da lì.
Mi chiedo se questo sia in realtà un progetto più chiaro però ... La classe Task ora sembra un po 'strana, essendo solo un'implementazione singola senza sottoclassi. Cosa ne pensate?