OO scelta di design e principio di responsabilità singola

4

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?

    
posta PJanssen 15.04.2014 - 14:54
fonte

1 risposta

2

Questa è fondamentalmente la domanda Composition vs. inheritance . Nel tuo primo caso, usi l'ereditarietà come modo per condividere il comportamento. In seconda istanza, usi la composizione. Inoltre, nel secondo caso, è facile identificare un modello di strategia in IDownloadClient . Quindi alcuni direbbero che il secondo caso è migliore.

Ma c'è anche KISS e YAGNI . Il tuo secondo caso si sta già complicando per la funzione che dovrebbe svolgere. È discutibile se hai davvero bisogno di un disegno così astratto.

Se fossi io, userei il primo, ma tengo a mente il secondo se entrano in gioco più requisiti, che potrebbero richiedere una complicazione dell'intero progetto.

    
risposta data 15.04.2014 - 15:40
fonte

Leggi altre domande sui tag