Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

Violare il contratto che un metodo ci garantisce

Uno dei miliardi di concetti che Code Complete 2 mi sta lasciando in testa riguarda i metodi che implementiamo nel nostro codice. Sembra una sciocchezza, però una dichiarazione di metodo fatta in questo modo...

public DomainModelObject GetAvaiableStream() { bool isValid; DomainModelObject ret; // Codice che fa chissà cosa if(isValid) return(ret); else return(null); }

Questo metodo, puramente casuale e senza alcuna utilità, ci ritorna un'istanza della classe DomainModelObject creata in chissà quale modo. Questo metodo, un po' come succede per l'interfaccia esposta dalle classi, crea un contratto. Garantisce che la sua chiamata ritorna un oggetto di questo tipo. La firma di un metodo ci dice una cosa del tipo: io ti assicuro che se mi chiami e mi passi gli oggetti che necessito per fare la mia elaborazione, io ti garantisco la restituzione di un oggetto di un certo tipo. In questo caso, di oggetti passati in input non ce ne sono, mentre l'oggetto ritornato è appunto un DomainModelObject.

Nel codice qui sopra c'è volutamente un errore. Non di compilazione, sia chiaro, ma un errore logico, che rompe il contratto e rende un po' più inconsistente il codice. Vediamo perchè.

Il codice dovrebbe creare un'istanza di DomainModelObject.
Se ci riesce, isValid è true, e l'oggetto viene effettivamente ritornato al chiamante.
Se non ci riesce, isValid è false, e viene ritornato null.

Quest'ultimo caso manda in fumo il design del metodo e della classe. Ritornare null significa che il chiamante deve prendersi cura di controllare questa cosa, per non scatenare un bel NullReferenceException. E' molto meglio rispettare questo contratto, evitando di riempire il nostro codice di if o di Exception. Se il test lo facciamo nel metodo - ed in effetti c'è già - possiamo isolare il problema e ritornare una sorta di InvalidDomainModelObject - istanza reale di una classe concreta derivata di DomainModelObject - che è ovviamente != null.

La classe InvalidDomainModelObject è a tutti gli effetti un DomainModelObject, quindi, ma permette di mantenere valido il contratto del metodo. In questa classe dovremmo fare l'overloading dei metodi, per renderli inoffensivi.

Per maggiori informazioni, chiedete a Martin Fowler e al suo pattern Special Case!

Print | posted on venerdì 27 ottobre 2006 19:15 | Filed Under [ Sviluppo .NET ]

Feedback

Gravatar

# Re: Violare il contratto che un metodo ci garantisce

osservazione giusta. Special case serve per differenziare tra diversi tipi di istanze "non valide". null vuol dire null e basta: vuol dire tanto o poco, dipende.
Con Special Case puoi avere MissingDomainModelObject, InvalidDomainModelObject, NotAvaiableDomainModelObject, etc. etc.
Inoltre, un'osservazione: Special Case mantiene stabile un sw evitando exception, anche se potresti avere comportamenti inattesi.
27/10/2006 20:12 | Igor Damiani
Gravatar

# re: Violare il contratto che un metodo ci garantisce

Un dubbio sollevato anche agli architecture days. Sono un po' scettico sui DummyObject. Ho raggiunto quota 100+ entità, che diventerebbero 300+ se utilizzassi anche questo tipo di oggetto. Mah...
27/10/2006 21:30 | Tommaso Caldarola
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET