2013-08-18 16 views
9

Guardavo attraverso il codice sorgente di Orchard CMS Project e ho notato che alcuni dei loro costruttori non verificavano mai che il parametro richiesto non fosse nullo. All'inizio pensavo che fosse strano. Ho chiesto a me stesso: "Considerando che stai dicendo che questa dipendenza è richiesta, non vorresti controllare che ne hai effettivamente uno?" Rendendosi conto che il progetto utilizza Castle Windsor come contenitore IoC, in seguito pensai: "Bene, il contenitore avrebbe generato un'eccezione quando cercava di trovare la dipendenza per l'oggetto che aveva il requisito." Quindi la mia domanda è valida, dovrei controllare ancora quando so che un container IoC controllerà per me?Con un contenitore IoC, un costruttore dovrebbe ancora verificare se un parametro è nullo?

Oppure il doppio controllo è buono perché, in un certo senso, sto aderendo a un principio di incapsulamento inverso affermando: "Non so come sto ottenendo questa dipendenza, ma ne ho davvero bisogno!"

+1

Ecco un interessante articolo di Mark Seemann su questo argomento: http://blog.ploeh.dk/2013/07/08/defensive-coding/ – Steven

+0

Grazie per quello .... Sto diventando silenzioso il fan di Marco. Ho sempre detto che dovresti verificare i requisiti del metodo prima dell'elaborazione perché semplifica la risoluzione dei problemi quando si incontra un problema. – Chris

+2

Per la verità, oggigiorno non controllo più gli argomenti del costruttore per le classi che sono cablate dal contenitore. So che il mio contenitore (e la maggior parte dei contenitori) non consentirà mai l'iniezione di null nel costruttore. Quindi lasciare fuori i controlli in quel caso è sicuro e rende il codice più leggibile, più mantenibile. – Steven

risposta

5

Sono stato portato a seguire la pratica di controllare ogni parametro visibile per NULL indipendentemente da come è stato progettato per essere istanziato. C'è sempre la possibilità che qualcuno scelga un contenitore IoC diverso che imponga una politica di delega più ampia o che uno sviluppatore minore trovi il tuo codice e spera che funzioni come preferisce.

In entrambi i casi, meglio prevenire che curare. In questo caso è meglio spendere un paio di secondi a guardia del codice, quindi ore quando qualcuno decide di usarlo come non intenzionale.

+2

È così che ho sempre pensato. Ma questa situazione mi ha fatto capire che in tutto il mio codice di produzione non ho mai avuto un'eccezione ArgumentNullException in un costruttore a causa del contenitore IoC. Sembrava solo un rumore in più nel mio codice. – Chris

4

Non vorrei controllare. Penso che ingombrerà inutilmente i tuoi costruttori.

Se il contenitore DI non ha la dipendenza richiesta, il test, il manuale o l'automatico dovrebbero rilevarlo molto rapidamente.

Avendo qualcosa come parametro per un costruttore, stai dicendo che è richiesto.

Inoltre, che cosa fai se ottieni in qualche modo un parametro nullo?

Il costruttore tenta di costruire un nuovo tipo null? Probabilmente no perché questo costruttore non dovrebbe avere idea di cosa il tipo passato debba istanziare da solo.

A questo punto si dovrebbe solo prendere l'eccezione e uscire con grazia o andare avanti; ma dovresti avere il codice per questa situazione comunque.

+3

Sto solo sostenendo l'avvocato del diavolo ... Non sarebbe l'ArgumentNullException essere più eloquente rispetto a NullReferenceException quando si risolve il problema? – Chris

+0

Come per la programmazione, penso che siamo nel regno delle preferenze. – tom

+1

I metodi più piccoli ottengono meno è necessario ottenere un 'NullReferenceException', perché più facile è individuare quale riferimento è nullo :-) – Steven

1

Sì. Il design di classe deve essere indipendente dal modo in cui le sue dipendenze vengono iniettate e deve sempre proteggere i suoi invarianti.

3

Le ultime versioni di Ninject e Structure eseguiranno entrambe un'eccezione di rilegatura prima di entrare nel costruttore. Quindi avere un controllo per argomento null eccezione nel costruttore non aiuterà comunque.

Quindi voto per mantenere pulito il codice.

Non sto dicendo che il codice difensivo non ha un posto, ma i controlli del costruttore non lo sono se si sta utilizzando l'IoC moderno.

Mentre c'è sempre la possibilità che qualcuno in futuro scelga un contenitore IoC diverso che non impone un rigido criterio di delega del tipo. Ritengo che sia un argomento "what if", il cambiamento di IoC è una decisione di architettura piuttosto grande e personalmente il costo dell'auto generazione di assegni nulli probabilmente non peserebbe molto su di esso.

Per me il probabile cappuccio di qualcuno che arriva e che ha bisogno di leggere il tuo codice è molto più alto.Il codice più facile da leggere è in genere meno probabile che sia bacato ed è anche più rapido da mantenere.

Problemi correlati