|
a risolvere tutti i problemi, ma mai nessuna di esse potra' porne uno. Einstein
|
|
| Home Page |
|
| Articoli |
|
| News |
|
| Forum |
|
| Classi |
|
|
|
|
|
La Dependency Injection e il TDD in Applicazioni Enterprise
By
Alessandro Rocca e Stefano Rossini
5 maggio 2008
|
 |
|
Tanti progetti Software falliscono per la mancanza di sufficienti e adeguati test dell'applicazione. Spesso questo è dovuto più a problemi organizzativi e culturali che a problemi tecnologici. Sicuramente il testing di applicazioni Enterprise rende la questione test ancora più importante, delicata e “spinosa” visto che i componenti software da testare necessitano l’utilizzo di Application Server (Servlet Container, EJB Container, JNDI, JTA,…) In questi articoli vedremo come i cosiddetti Framework POJO (Plain Old Java Objects), basati sul pattern Inversion Of Control, agevolino il Test Driven Development (TDD) nell’ambito del testing di applicazioni Enterpise. In questa prima parte parleremo della pratica per lo sviluppo del software TDD e del pattern Inversion Of Control (IoC). Nel seguito proporremo alcuni esempi pratici utilizzando i Framework POJO Spring e EJB 3.0.
|
|
|
TDD
|
top
|
|
Il Test Driven Development (TDD) è una pratica agile di sviluppo software incentrata sui test. Seguendo tale pratica lo sviluppo tradizionale viene "stravolto": in TDD si crea in primo luogo il codice di test della funzionalità d'interesse, poi il codice applicativo che implementa tale funzione [SATDD]. In tale ottica lo sviluppo del codice applicativo è subordinato all’esito dell’esecuzione del relativo test. Fino a quando non si otterrà un esito positivo dall’esecuzione del test, lo sviluppo del codice applicativo è da considerarsi non terminato.

Figura 1 - Test Driven Development [MOKATDD]
Sviluppare secondo il TDD garantisce che per tutto il codice sviluppato esista un test associato. Si arriva a realizzare, parallelamente al codice applicativo, una suite di test completa; questo da un lato aumenta la confidenza sulla robustezza del proprio codice sviluppato, dall’altro “semplifica” il refactoring e l’introduzione di nuove funzionalità (lo sviluppatore può sempre contare su una suite consistente di test).
|
|
Inversion Of Control (Dependency Injection)
|
top
|
|
Il nome del pattern, Inversion of Control (anche conosciuto con il nome Dependency Injection) è stato coniato nel 2004 da Martin Fowler [MFIOC].
L’Inversion of Control (IoC) permette di descrivere come gli oggetti debbano essere valorizzati e con quali altri oggetti hanno delle dipendenze. Il container è il responsabile del collegamento fra questi oggetti, poiché istanzia e inietta le dipendenze tra i vari oggetti.
Il concetto quindi alla base dell'IoC è che le dipendenze con gli altri oggetti non vengono risolte direttamente dall’oggetto stesso ma da una infrastruttura esterna. Un oggetto “riceve quindi automaticamente” i riferimenti agli oggetti collaboranti dall'esterno attraverso opportune configurazioni. È l'infrastruttura esterna ad avere la responsabilità di istanziare gli oggetti e di fornire loro (injection) le relative dipendenze in base a delle opportune informazioni di configurazione (sollevando da tale responsabilità l’applicazione stessa).
Minimizzare le dipendenze fra gli oggetti significa facilitare il riutilizzo dei componenti e rendere più semplice, cosa fondamentale in ottica TDD, lo sviluppo di test ottenendo di conseguenza un'applicazione più robusta.
Esistono tre tipi di implementazione dell' Inversion of Control:
- tipo1: i servizi implementano una interfaccia dedicata
- tipo2: (Setter based), le dipendenze vengono assegnate settando dei valori a dei JavaBeans
- tipo3: (Constructor based), le dipendenze vengono assegnate passando degli argomenti ai costruttori
L'Inversion of Control è un pattern che rispetta il principio di Hollywood: "Don't call us, we'll call you" [WP_HP], la cui implementazione può essere effettuata ad esempio mediante XML (Spring) o tagging (EJB 3.0).
Per inciso, il termine iniettare ricorda una definizione alternativa per il pattern IoC, la Dependency Injection (DI).
La Dependency Injection risulta essere una nuova soluzione al problema del recupero di risorse e servizi, promuovendo l’iniezione degli stessi in antitesi con il pattern più classico del Service Locator, che utilizza JNDI.
La figura seguente confronta i due differenti pattern, Service Locator e Dependency Injection, in caso di recupero di un DataSource.

Figura 2 - Service Locator Vs Dependency Injection
|
|
I Framework POJO
|
top
|
|
Il pattern Inversion of Control è alla base dei Framework Spring e EJB 3.0 [PAF].
Spring è un’implementazione di framework POJO open source ed è principalmente sviluppato e controllato da Interface21 Inc., mentre EJB 3.0 è una specifica definita dalla Java Community Process (JCP) .
Entrambi condividono la stessa filosofia di design, ovvero quella di disaccoppiare i POJO (Plain Old Java Objects) dai servizi middleware, mettendo a disposizione gli uni agli altri a run-time mediante iniezione.
Sebbene condividano la stessa filosofia di fondo, i due framework utilizzano un approccio molto diverso per la gestione dell’injection.
Spring basa il meccanismo della Dependency Injection sull’utilizzo di file di configurazione XML, mentre EJB 3.0 (J2EE 5 in generale) fa un uso massiccio di Java annotation.

Figura 3 - Dependency Injection: Spring & EJB 3.0
La Dependency Injection permette di utilizzare la propria classe Java di Business (Business Object) in scenari multipli; si può utilizzare la stessa classe in una Desktop Application oppure riusarla in ambiente “managed”, cioè un Application Server (Servlet Container e/o EJB Container). Tali differenti scenari si ottengono modificando opportunamente le configurazioni a parità di class !
Figura 4 - Flessibilità della Dependency Injection
|
|
Dependency Injection & TDD
|
top
|
|
L'essenza della Dependency Injection applicata al Test Driven Development consiste nella possibilità di testare scenari multipli (environment managed, unmanaged, mock) attraverso altrettante configurazioni.
Con il supporto della Dependency Injection lo sviluppatore può sviluppare ed eseguire test di unità anche senza Container, senza Database (DB), totalmente offline. Da questo si intuisce che le applicazioni che usano Framework POJO come Spring o J2EE 5 risultano più semplici da testare, sia da un punto di vista infrastrutturale, sia di tempi richiesti per l’esecuzione degli stessi (es: nessun re-deploy per ogni modifica del sorgente, nessun tempo di attesa per il restart degli Application Server, …).
Per dare un’idea dei benefici risultanti dall’uso di un Framework POJO e della relativa infrastruttura DI è sufficiente pensare al classico sviluppo di test In-Container (es: test Junit per verifica del corretto funzionamento di EJB 2.1 all’interno di un Application Server). Solitamente uno sviluppatore che utilizza un Framework J2EE “heavyweight” deve sviluppare, effettuare il deploy nel container dell’Application Server (Servlet e/o EJB), aspettare l’avvenuta installazione, avviare l'Applicazione e quindi eseguire i test. Senza l’ausilio di una infrastruttura DI questo ciclo di sviluppo e test richiede frequenti procedure di avvio e deploy, con conseguente perdita di tempo e concentrazione, soprattutto quando la macchina dello sviluppatore è “poco carrozzata” (es: poca RAM) e/o l’Application Server è particolarmente “pesante” (es: richiede uno startup complesso oppure non supporta in modo affidabile la procedura di hot deploy).

Figura 5 – Testing In-Container
Utilizzando un Framework POJO, un programmatore può invece procedere nelle attività di sviluppo anche senza container e/o DB ! Potendo effettuare il testing Out-Of-Container, il suo ciclo di lavoro è sviluppare ed eseguire i test senza dover dipendere da (re)deploy e/o restart dell’Application Server.
E' facile intuire che il programmatore che utilizza il Framework POJO (“lightweight”) svilupperà codice di migliore qualità (più test, più robustezza) guadagnando in tempo e … in salute:
- le applicazioni non contengono codice che mappa direttamente servizi J2EE
- le configurazioni sono esterne alle applicazioni
- la Dependency Injection facilita lo unit test ed il TDD

Figura 6 - Testing Out-Of-Container
|
|
Conclusioni
|
top
|
La Dependency Injection rende semplice l’esecuzione del proprio codice al di fuori degli Application Server permettendo di testare le proprie classi Java in modo isolato, agile ed efficace. Per esempio, possiamo testare il codice senza che il Data Access Object faccia effettivamente riferimento al DB oppure iniettare facilmente oggetti Mock. Questo permette di verificare il funzionamento di un Business Object / DAO al di fuori del Container e successivamente, solo quando i test danno esito positivo, si può procedere all’installazione e configurazione nel container. A parità di bytecode (.class) l’oggetto può girare in modalità standalone (per agevolare il testing o per essere riusato in applicazioni Desktop) o all’interno di un container (utilizzando quindi i servizi dell’Application Server).
L’idea di poter usufruire in modo agile di Testing Out-Of-Container, pone l’attenzione sull’estensione dell’applicabilità della pratica TDD, di per sè agile, in progetti di tipo Enterprise in cui si faccia uso di Framework POJO. A noi piace indicare questo scenario con il termine “Enterprise TDD”.

Figura 7 - “Enterprise TDD”
Dopo questa introduzione sulle potenzialità dei Framework POJO Lightweight che sfruttano il pattern Inversion of Control e i grandi vantaggi in termini di flessibilità e di test che offre, nei prossimi due articoli presenteremo degli esempi pratici basandoci sul FWK Spring. e EJB 3.0.
|
|
Bibliografia
|
top
|
[SATDD] Scott W. Ambler: Test Driven Development
[MOKATDD] S. Rossini: Pratiche di sviluppo del software (I): Test Driven Development
[MFIOC] M. Fowler: Inversion of Control Containers and the Dependency Injection pattern
[HP_WP] http://en.wikipedia.org/wiki/Hollywood_Principle
[DIJEE5] D. Panda: Using Dependency Injection in Java EE 5.0
[RJITSF] R.Johnson: Introducing to the Spring Framework
[PAF] M.J.Yuan: POJO Application Frameworks: Spring Vs. EJB 3.0
[SPRING] Framework Spring
[EJB3.0] Enterprise JavaBeans Technology
|
|
|

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons
|
|
|