Il post di Bob Martin L'architettura pulita ti consiglia di le dipendenze della classe dovrebbero puntare verso l'interno, non verso l'esterno.
The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity.
Seguito alla lettera significa che la tua biblioteca interna non farebbe nemmeno riferimento a una libreria esterna. Invece, definirebbe le proprie interfacce e quindi le librerie aggiuntive creerebbero composizioni che combinano le vostre classi interne con le implementazioni delle interfacce da cui dipende.
(Non l'ho mai visto, non lo sto deridendo come poco pratico, sembra fantastico e voglio implementarlo su larga scala prima che muoia.)
Su una scala più piccola puoi ottenere alcuni dei vantaggi assicurando che le tue classi dipendano da interfacce definite dall'utente, non su interfacce definite esternamente.
Usando un esempio molto semplice, potresti definire la tua interfaccia di registrazione, come
public interface ILogger
{
void LogException(Exception ex);
}
Ora se una classe ha bisogno di registrare le eccezioni, dipende solo da quell'interfaccia, non da un'interfaccia Microsoft o da un'interfaccia di Windsor, o qualsiasi altra cosa. Quindi, se stai utilizzando una libreria di log esterna, crei un'implementazione di ILogger
che include una chiamata a quella libreria.
La cosa fantastica di questo è che ora stai raggiungendo la segregazione dell'interfaccia. Le tue classi hanno meno probabilità di dipendere da qualsiasi interfaccia gigante che il mondo gli fornisce e più probabilmente dipenderanno da interfacce di piccole dimensioni che forniscono esattamente ciò di cui la classe ha bisogno.
Quindi, tornando alla tua domanda iniziale, quelle interfacce saranno facili da prendere in giro. Potrebbero anche essere così piccoli da rendere più facile l'uso di semplici doppie classi di test anziché di una struttura di derisione. Mi piace usare Moq ma a volte tutte queste impostazioni diventano difficili da leggere. Se posso facilmente scrivere una classe come PermissionsValidatorThatAlwaysReturnsTrue
, allora potrei andare avanti e scrivere le poche righe di codice in più. Il tempo potrebbe essere salvato quando qualcuno vede quella classe usata in un test, la naviga e vede quello che fa, invece di cercare di capire quale% di co_de viene usato e come è stato impostato.